diff --git a/command.go b/command.go
index 5b81f61d..5f1caccc 100644
--- a/command.go
+++ b/command.go
@@ -1056,7 +1056,25 @@ func (c *Command) InitDefaultHelpCmd() {
 			Short: "Help about any command",
 			Long: `Help provides help for any command in the application.
 Simply type ` + c.Name() + ` help [path to command] for full details.`,
-
+			ValidArgsFunction: func(c *Command, args []string, toComplete string) ([]string, ShellCompDirective) {
+				var completions []string
+				cmd, _, e := c.Root().Find(args)
+				if e != nil {
+					return nil, ShellCompDirectiveNoFileComp
+				}
+				if cmd == nil {
+					// Root help command.
+					cmd = c.Root()
+				}
+				for _, subCmd := range cmd.Commands() {
+					if subCmd.IsAvailableCommand() || subCmd == cmd.helpCommand {
+						if strings.HasPrefix(subCmd.Name(), toComplete) {
+							completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
+						}
+					}
+				}
+				return completions, ShellCompDirectiveNoFileComp
+			},
 			Run: func(c *Command, args []string) {
 				cmd, _, e := c.Root().Find(args)
 				if cmd == nil || e != nil {
diff --git a/custom_completions.go b/custom_completions.go
index ba57327c..47cc9f5a 100644
--- a/custom_completions.go
+++ b/custom_completions.go
@@ -183,10 +183,12 @@ func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDi
 	}
 
 	if flag == nil {
-		// Complete subcommand names
+		// Complete subcommand names, including the help command
 		for _, subCmd := range finalCmd.Commands() {
-			if subCmd.IsAvailableCommand() && strings.HasPrefix(subCmd.Name(), toComplete) {
-				completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
+			if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {
+				if strings.HasPrefix(subCmd.Name(), toComplete) {
+					completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
+				}
 			}
 		}
 
diff --git a/custom_completions_test.go b/custom_completions_test.go
index 86154839..fe15263c 100644
--- a/custom_completions_test.go
+++ b/custom_completions_test.go
@@ -629,3 +629,71 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) {
 		t.Errorf("expected: %q, got: %q", expected, output)
 	}
 }
+
+func TestCompleteHelp(t *testing.T) {
+	rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
+	child1Cmd := &Command{
+		Use: "child1",
+		Run: emptyRun,
+	}
+	child2Cmd := &Command{
+		Use: "child2",
+		Run: emptyRun,
+	}
+	rootCmd.AddCommand(child1Cmd, child2Cmd)
+
+	child3Cmd := &Command{
+		Use: "child3",
+		Run: emptyRun,
+	}
+	child1Cmd.AddCommand(child3Cmd)
+
+	// Test that completion includes the help command
+	output, err := executeCommand(rootCmd, ShellCompNoDescRequestCmd, "")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	expected := strings.Join([]string{
+		"child1",
+		"child2",
+		"help",
+		":0",
+		"Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n")
+
+	if output != expected {
+		t.Errorf("expected: %q, got: %q", expected, output)
+	}
+
+	// Test sub-commands are completed on first level of help command
+	output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "help", "")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	expected = strings.Join([]string{
+		"child1",
+		"child2",
+		"help", // "<program> help help" is a valid command, so should be completed
+		":4",
+		"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n")
+
+	if output != expected {
+		t.Errorf("expected: %q, got: %q", expected, output)
+	}
+
+	// Test sub-commands are completed on first level of help command
+	output, err = executeCommand(rootCmd, ShellCompNoDescRequestCmd, "help", "child1", "")
+	if err != nil {
+		t.Errorf("Unexpected error: %v", err)
+	}
+
+	expected = strings.Join([]string{
+		"child3",
+		":4",
+		"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n")
+
+	if output != expected {
+		t.Errorf("expected: %q, got: %q", expected, output)
+	}
+}