diff --git a/gopls/internal/golang/hover.go b/gopls/internal/golang/hover.go
index 296434b3270..3661a8eb515 100644
--- a/gopls/internal/golang/hover.go
+++ b/gopls/internal/golang/hover.go
@@ -13,6 +13,7 @@ import (
 	"go/constant"
 	"go/doc"
 	"go/format"
+	"go/parser"
 	"go/token"
 	"go/types"
 	"io/fs"
@@ -398,8 +399,15 @@ func hover(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, pp pro
 		// including those that require a pointer receiver,
 		// and those promoted from embedded struct fields or
 		// embedded interfaces.
-		var b strings.Builder
-		for _, m := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
+		var (
+			b strings.Builder
+			// methodDocs is a map of the method name and it associated documentation.
+			methodDocs = make(map[string]string)
+		)
+		methodSetOfHoveredType := typeutil.IntuitiveMethodSet(obj.Type(), nil)
+		lenOfMethodSet := len(methodSetOfHoveredType)
+		methodNameArray := make([]string, 0, lenOfMethodSet)
+		for _, m := range methodSetOfHoveredType {
 			if !accessibleTo(m.Obj(), pkg.Types()) {
 				continue // inaccessible
 			}
@@ -412,10 +420,38 @@ func hover(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, pp pro
 
 			// Use objectString for its prettier rendering of method receivers.
 			b.WriteString(objectString(m.Obj(), qf, token.NoPos, nil, nil))
+			methodNameArray = append(methodNameArray, m.Obj().Name())
+			methodDocs[m.Obj().Name()] = ""
 		}
 		methods = b.String()
 
 		signature = typeDecl + "\n" + methods
+
+		// -- method doc --
+		{
+			if len(methodNameArray) > 0 { // if we have methods at all from methodSet
+				fs := token.NewFileSet()
+				if allPkgsInDir, err := parser.ParseDir(fs, declPGF.URI.Dir().Path(), nil, parser.ParseComments); err == nil {
+					if files, ok := allPkgsInDir[obj.Pkg().Name()]; ok {
+						for _, file := range files.Files {
+							getMethodDoc(file, fs, ident, methodDocs)
+						}
+
+						methodArray := strings.Split(methods, "\n")
+						if m := len(methodArray); m > 0 && m == len(methodNameArray) {
+							var d strings.Builder
+							for i := 0; i < m; i++ {
+								if doc, ok := methodDocs[methodNameArray[i]]; ok {
+									d.WriteString(fmt.Sprintf("```go\n%s\n```\n%s\n", methodArray[i], doc))
+								}
+							}
+							methods = d.String()
+						}
+					}
+				}
+			}
+		}
+
 	} else {
 		// Non-types
 		if sizeOffset != "" {
@@ -1063,6 +1099,13 @@ func formatHover(h *hoverJSON, options *settings.Options) (string, error) {
 		return s
 	}
 
+	fallback := func(s string) string {
+		if !strings.Contains(s, "```go") {
+			return maybeMarkdown(s)
+		}
+		return s
+	}
+
 	switch options.HoverKind {
 	case settings.SingleLine:
 		return h.SingleLine, nil
@@ -1089,7 +1132,7 @@ func formatHover(h *hoverJSON, options *settings.Options) (string, error) {
 			maybeMarkdown(h.typeDecl),
 			formatDoc(h, options),
 			maybeMarkdown(h.promotedFields),
-			maybeMarkdown(h.methods),
+			fallback(h.methods),
 			formatLink(h, options),
 		}
 		if h.typeDecl != "" {
@@ -1409,3 +1452,31 @@ func computeSizeOffsetInfo(pkg *cache.Package, path []ast.Node, obj types.Object
 
 	return
 }
+
+// getMethodDoc populates the map type parameter(methodDocs) with the respective docs,
+// if the key (method name) is present in the map.
+func getMethodDoc(file *ast.File, fs *token.FileSet, hoveredType *ast.Ident, methodDocs map[string]string) {
+	ast.Inspect(file, func(n ast.Node) bool {
+		if fn, ok := n.(*ast.FuncDecl); ok {
+			if recv := fn.Recv; recv != nil { // if it is a method
+				if recvList := recv.List; len(recvList) == 1 { // as it should always be
+					methodType := types.ExprString(recvList[0].Type)
+					rFmethodType, _ := strings.CutPrefix(methodType, "*") // if it a pointer
+
+					if rFmethodType == hoveredType.Name {
+						fnPos := fn.Pos()
+						f := fs.File(fnPos)
+						filname, lineNumber := f.Name(), f.Line(fnPos)
+						pageSourceURL := fmt.Sprintf("[jump to page source](%s#L%d)", filname, lineNumber)
+
+						methodDocs[fn.Name.Name] = strings.TrimSpace(fn.Doc.Text()) + "\n\n" + pageSourceURL
+						return false
+					}
+				}
+				return true
+			}
+			return true
+		}
+		return true
+	})
+}