diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 08c7c6c1f4..322b539417 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* cli/cli-cmds.h: Export complete_command.
+	* cli/cli-cmds.c (complete_command): Update to print completions
+	on MI channel if requested.
+	* mi/mi-cmds.c: Define new -complete command implemented using
+	it CLI command 'complete'.
+	* NEWS: Mention new -complete command.
+
 2018-12-17  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* dwarf2read.c (struct dwarf2_cu): Convert the fields 'mark',
diff --git a/gdb/NEWS b/gdb/NEWS
index 913f3ae3b6..6b561af71f 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -96,6 +96,13 @@ maint show dwarf unwinders
 info proc files
   Display a list of open files for a process.
 
+* New MI commands
+
+-complete
+  This lists all the possible completions for the rest of the line, if it
+  were to be given as a command itself.  This is intended for use by MI frontends
+  in cases when separate CLI and MI channels cannot be used.
+
 * Changed commands
 
 target remote FILENAME
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 135f550b80..468f66dac6 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -223,16 +223,22 @@ help_command (const char *command, int from_tty)
 /* Note: The "complete" command is used by Emacs to implement completion.
    [Is that why this function writes output with *_unfiltered?]  */
 
-static void
+void
 complete_command (const char *arg, int from_tty)
 {
+  struct ui_out *uiout = current_uiout;
+  bool is_mi_like = uiout->is_mi_like_p ();
+
   dont_repeat ();
 
   if (max_completions == 0)
     {
-      /* Only print this for non-mi frontends.  An MI frontend may not
-	 be able to handle this.  */
-      if (!current_uiout->is_mi_like_p ())
+      if (is_mi_like)
+        {
+          error (_("max-completions is zero,"
+		   " completion is disabled.\n"));
+        }
+      else
 	{
 	  printf_unfiltered (_("max-completions is zero,"
 			       " completion is disabled.\n"));
@@ -278,34 +284,61 @@ complete_command (const char *arg, int from_tty)
   completion_result result
     = tracker->build_completion_result (word, word - arg, strlen (arg));
 
-  if (result.number_matches != 0)
-    {
-      if (result.number_matches == 1)
-	printf_unfiltered ("%s%s\n", arg_prefix.c_str (), result.match_list[0]);
-      else
-	{
-	  result.sort_match_list ();
-
-	  for (size_t i = 0; i < result.number_matches; i++)
-	    {
-	      printf_unfiltered ("%s%s",
-				 arg_prefix.c_str (),
-				 result.match_list[i + 1]);
-	      if (quote_char)
-		printf_unfiltered ("%c", quote_char);
-	      printf_unfiltered ("\n");
-	    }
-	}
-
-      if (result.number_matches == max_completions)
-	{
-	  /* ARG_PREFIX and WORD are included in the output so that emacs
-	     will include the message in the output.  */
-	  printf_unfiltered (_("%s%s %s\n"),
-			     arg_prefix.c_str (), word,
-			     get_max_completions_reached_message ());
-	}
+  {
+    ui_out_emit_list completions_emitter (uiout, "completions");
+    if (result.number_matches != 0)
+      {
+        if (result.number_matches == 1)
+          {
+	    if (is_mi_like)
+	      uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (),
+                                             result.match_list[0]);
+	    else
+	      printf_unfiltered ("%s%s\n", arg_prefix.c_str (),
+                                           result.match_list[0]);
+          }
+        else
+	  {
+	    result.sort_match_list ();
+
+	    for (size_t i = 0; i < result.number_matches; i++)
+	      {
+                if (is_mi_like)
+	          {
+	            uiout->field_fmt(NULL, "%s%s", arg_prefix.c_str (),
+                                                   result.match_list[i + 1]);
+	          }
+	        else
+	          {
+		    printf_unfiltered ("%s%s", arg_prefix.c_str (),
+                                               result.match_list[i + 1]);
+		    if (quote_char)
+		      printf_unfiltered ("%c", quote_char);
+		    printf_unfiltered ("\n");
+	          }
+	      }
+	  }
+      }
     }
+
+    if (result.number_matches == max_completions)
+      {
+	if (is_mi_like)
+	  uiout->field_string("max_completions_reached", "1");
+	else
+	  {
+	    /* ARG_PREFIX and WORD are included in the output so that emacs
+	       will include the message in the output.  */
+	    printf_unfiltered (_("%s%s %s\n"),
+				 arg_prefix.c_str (), word,
+				 get_max_completions_reached_message ());
+	  }
+      }
+    else
+      {
+	if (is_mi_like)
+	  uiout->field_string("max_completions_reached", "0");
+      }
 }
 
 int
diff --git a/gdb/cli/cli-cmds.h b/gdb/cli/cli-cmds.h
index 3fa188dba6..bcd12c0c0b 100644
--- a/gdb/cli/cli-cmds.h
+++ b/gdb/cli/cli-cmds.h
@@ -106,6 +106,10 @@ void init_cmd_lists (void);
 
 void init_cli_cmds (void);
 
+/* Exported to gdb/mi/mi-cmds.c */
+
+void complete_command (const char *, int);
+
 int is_complete_command (struct cmd_list_element *cmd);
 
 /* Exported to gdb/main.c */
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 68d3068c72..da81f6a6c1 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.texinfo (Miscellaneous GDB/MI Commands): Document new
+	MI command -complete.
+
 2018-12-13  John Baldwin  <jhb@FreeBSD.org>
 
 	* gdb.texinfo (Set Catchpoints): Add an anchor for 'catch syscall'.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index d766e44e63..7f88273145 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34236,6 +34236,38 @@ fullname="/home/nickrob/myprog.c",line="73",arch="i386:x86_64"@}
 (gdb)
 @end smallexample
 
+@subheading The @code{-complete} Command
+@findex -complete
+
+@subheading Synopsis
+
+@smallexample
+-complete @var{command}
+@end smallexample
+
+Show a list of completions for partially typed CLI @var{command}. The
+@var{command} should be given in verbatim without any quoting / escaping.
+
+This command is intended for @sc{gdb/mi} frontends that cannot use two separate
+CLI and MI channels - for example: because of lack of PTYs like on Windows or
+because @sc{gdb} is used remotely via a SSH connection.
+
+@subheading @value{GDBN} Command
+
+The corresponding @value{GDBN} command is @samp{complete}.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-complete br
+^done,completions=["break","break-range"],max_completions_reached="0"
+(gdb)
+-complete b madv
+^done,completions=["b madvise"],max_completions_reached="0"
+(gdb)
+@end smallexample
+
 @node Annotations
 @chapter @value{GDBN} Annotations
 
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 51014eded2..7b510f71d4 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -20,9 +20,11 @@
 
 #include "defs.h"
 #include "top.h"
+#include "cli/cli-cmds.h"
 #include "mi-cmds.h"
 #include "mi-main.h"
 
+
 struct mi_cmd;
 static struct mi_cmd **lookup_table (const char *command);
 static void build_table (struct mi_cmd *commands);
@@ -75,6 +77,7 @@ static struct mi_cmd mi_cmds[] =
                    &mi_suppress_notification.breakpoint),
   DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload,
                    &mi_suppress_notification.breakpoint),
+  DEF_MI_CMD_CLI ("complete", "complete", 1),
   DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble),
   DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression),
   DEF_MI_CMD_MI ("data-list-changed-registers",
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ab3a74fffd..40da71b2c5 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-01-03  Jan Vrany  <jan.vrany@fit.cvut.cz>
+
+	* gdb.mi/mi-complete.exp: New file.
+
 2018-12-12  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gdb.base/annota1.exp: Update a test regexp.
diff --git a/gdb/testsuite/gdb.mi/mi-complete.exp b/gdb/testsuite/gdb.mi/mi-complete.exp
new file mode 100644
index 0000000000..14c763a966
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-complete.exp
@@ -0,0 +1,71 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Verify -data-evaluate-expression. There are really minimal tests.
+
+# The goal is not to test gdb functionality, which is done by other tests,
+# but to verify the correct output response to MI operations.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile basics.c
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested "failed to compile"
+     return -1
+}
+
+mi_run_to_main
+
+mi_gdb_test "1-complete br" \
+            "1\\^done,completions=\\\[.*\"break\",.*\"break-range\".*\\\],max_completions_reached=\"0\"" \
+            "-complete br"
+
+# Check empty completion list
+mi_gdb_test "5-complete bogus" \
+            "5\\^done,completions=\\\[\\\],max_completions_reached=\"0\"" \
+            "-complete bogus"
+
+
+# Check completions for commands with space
+mi_gdb_test "4-complete b mai" \
+            "4\\^done,completions=\\\[.*\"b main\".*\\\],max_completions_reached=\"0\"" \
+            "-complete b mai"
+
+mi_gdb_test "-info-gdb-mi-command complete" \
+            "\\^done,command=\{exists=\"true\"\}" \
+            "-info-gdb-mi-command complete"
+
+# Limit max completions and check that max_completions_reached=\"0\" is set
+# to 1.
+send_gdb "set max-completions 1\n"
+
+mi_gdb_test "2-complete br" \
+            ".*2\\^done,completions=\\\[\"br\[A-Za-z0-9-\]+\"\\\],max_completions_reached=\"1\"" \
+            "-complete br (max-completions 1)"
+
+# Disable completions and check an error is returned
+send_gdb "set max-completions 0\n"
+
+mi_gdb_test "3-complete br" \
+            ".*3\\^error,msg=\".*" \
+            "-complete br (max-completions 1)"
