I know that Bmesh is a standalone module and bpy is an application module. But still why we have mesh related operations under bpy i.e bpy.ops.mesh , if we have bmesh? I need deep insight.
Pretty much all Blender's functions that you use in the UI must have their operators. This is just how Blender works. The UI is defined with Python and there must be a way to edit meshes from the UI so bpy operators exist. Mesh operators are better designed to be used by a human user. For example, they often require interactive user input. They are not designed with usage from scripts as the main goal.
BMesh is a tool for programmatically accessing Blender's internal modelling functionality. It is created for coding, flexibility, efficiency and speed of scripts manipulating meshes. When scripting and programing you usually want to do more with geometry than it would make sense for a UI user. BMesh is supposed to be for that. It is designed to access Blender's modelling functionality programmatically from a script as opposed to by a user.
In addition to what @Martin Z said, bpy.ops.mesh predates the introduction of BMesh in Blender. Most of the operators were already in blender, and continued to function in much the same way, even though internally in the C code they have been updated to take advantage of the BMesh data structures. Thus for reasons of script compatibility it makes sense to keep them where they were in the API.