Index: lldb/include/lldb/Interpreter/CommandCompletions.h
===================================================================
--- lldb/include/lldb/Interpreter/CommandCompletions.h
+++ lldb/include/lldb/Interpreter/CommandCompletions.h
@@ -38,10 +38,11 @@
     eBreakpointCompletion = (1u << 10),
     eBreakpointNameCompletion = (1u << 11),
     eProcessPluginCompletion = (1u << 12),
+    eProcessIDCompletion = (1u << 13),
     // This item serves two purposes.  It is the last element in the enum, so
     // you can add custom enums starting from here in your Option class. Also
     // if you & in this bit the base code will not process the option.
-    eCustomCompletion = (1u << 13)
+    eCustomCompletion = (1u << 14)
   };
 
   static bool InvokeCommonCompletionCallbacks(
@@ -99,6 +100,9 @@
   static void ProcessPluginNames(CommandInterpreter &interpreter,
                                  CompletionRequest &request,
                                  SearchFilter *searcher);
+
+  static void ProcessIDs(CommandInterpreter &interpreter,
+                         CompletionRequest &request, SearchFilter *searcher);
 };
 
 } // namespace lldb_private
Index: lldb/source/Commands/CommandCompletions.cpp
===================================================================
--- lldb/source/Commands/CommandCompletions.cpp
+++ lldb/source/Commands/CommandCompletions.cpp
@@ -60,6 +60,7 @@
       {eBreakpointCompletion, CommandCompletions::Breakpoints},
       {eBreakpointNameCompletion, CommandCompletions::BreakpointNames},
       {eProcessPluginCompletion, CommandCompletions::ProcessPluginNames},
+      {eProcessIDCompletion, CommandCompletions::ProcessIDs},
       {eNoCompletion, nullptr} // This one has to be last in the list.
   };
 
@@ -608,4 +609,25 @@
                                             SearchFilter *searcher) {
   PluginManager::AutoCompleteProcessName(request.GetCursorArgumentPrefix(),
                                          request);
+}
+
+void CommandCompletions::ProcessIDs(CommandInterpreter &interpreter,
+                                    CompletionRequest &request,
+                                    SearchFilter *searcher) {
+  lldb::PlatformSP platform_sp(interpreter.GetPlatform(true));
+  if (!platform_sp)
+    return;
+  ProcessInstanceInfoList process_infos;
+  ProcessInstanceInfoMatch match_info;
+  platform_sp->FindProcesses(match_info, process_infos);
+  const size_t num_matches = process_infos.size();
+  if (num_matches == 0)
+    return;
+  for (const ProcessInstanceInfo &info : process_infos) {
+    const llvm::StringRef process_name = info.GetNameAsStringRef();
+    if (process_name.empty())
+      continue;
+    request.TryCompleteCurrentArg(std::to_string(info.GetProcessID()),
+                                  process_name);
+  }
 }
\ No newline at end of file
Index: lldb/source/Commands/CommandObjectProcess.cpp
===================================================================
--- lldb/source/Commands/CommandObjectProcess.cpp
+++ lldb/source/Commands/CommandObjectProcess.cpp
@@ -355,6 +355,12 @@
             interpreter, CommandCompletions::eProcessPluginCompletion, request,
             nullptr);
         break;
+
+      case 'p':
+        CommandCompletions::InvokeCommonCompletionCallbacks(
+            interpreter, CommandCompletions::eProcessIDCompletion, request,
+            nullptr);
+        break;
       }
     }
 
Index: lldb/test/API/functionalities/completion/TestCompletion.py
===================================================================
--- lldb/test/API/functionalities/completion/TestCompletion.py
+++ lldb/test/API/functionalities/completion/TestCompletion.py
@@ -3,8 +3,8 @@
 """
 
 
-
 import os
+from multiprocessing import Process
 import lldb
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
@@ -92,6 +92,20 @@
             self.complete_from_to('process ' + subcommand + ' mac',
                                   'process ' + subcommand + ' mach-o-core')
 
+    @skipIfRemote
+    def test_process_attach_dash_p(self):
+        # The LLDB process itself and the process already attached to are both
+        # ignored by the process discovery mechanism, thus we need to create a 
+        # process known to us here.
+        def test():
+            while True:
+                time.sleep(1)
+        
+        p = Process(target=test, daemon=False)
+        p.start()
+        self.complete_from_to('process attach -p ', [str(p.pid)])
+        p.terminate()
+
     def test_process_signal(self):
         # The tab completion for "process signal"  won't work without a running process.
         self.complete_from_to('process signal ',