diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 05701ce19ccb946e004077511733bcbc71870762..f5e753882a3fbd76e72e869012c51df15209be2f 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -287,6 +287,13 @@
 
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
 
+// Employ an external closed loop controller. Override pins here if needed.
+//#define EXTERNAL_CLOSED_LOOP_CONTROLLER
+#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+  //#define CLOSED_LOOP_ENABLE_PIN        -1
+  //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1
+#endif
+
 /**
  * Dual Steppers / Dual Endstops
  *
diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp
index 9720d824facf9a02dd45296f013e384c6815e182..e7d4a37fe351b67b448604377f04d3d801de2498 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/Marlin.cpp
@@ -40,6 +40,8 @@
 #include "sd/cardreader.h"
 #include "module/configuration_store.h"
 #include "module/printcounter.h" // PrintCounter or Stopwatch
+#include "feature/closedloop.h"
+
 #ifdef ARDUINO
   #include <pins_arduino.h>
 #endif
@@ -903,6 +905,10 @@ void setup() {
   #if ENABLED(USE_WATCHDOG) // Reinit watchdog after HAL_get_reset_source call
     watchdog_init();
   #endif
+
+  #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+    init_closedloop();
+  #endif
 }
 
 /**
diff --git a/Marlin/src/config/default/Configuration_adv.h b/Marlin/src/config/default/Configuration_adv.h
index 05701ce19ccb946e004077511733bcbc71870762..f5e753882a3fbd76e72e869012c51df15209be2f 100755
--- a/Marlin/src/config/default/Configuration_adv.h
+++ b/Marlin/src/config/default/Configuration_adv.h
@@ -287,6 +287,13 @@
 
 //#define Z_LATE_ENABLE // Enable Z the last moment. Needed if your Z driver overheats.
 
+// Employ an external closed loop controller. Override pins here if needed.
+//#define EXTERNAL_CLOSED_LOOP_CONTROLLER
+#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+  //#define CLOSED_LOOP_ENABLE_PIN        -1
+  //#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1
+#endif
+
 /**
  * Dual Steppers / Dual Endstops
  *
diff --git a/Marlin/src/feature/closedloop.cpp b/Marlin/src/feature/closedloop.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2fe60fcf9c8a935650dcbafa624f34fab1c1ef3f
--- /dev/null
+++ b/Marlin/src/feature/closedloop.cpp
@@ -0,0 +1,41 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * 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/>.
+ *
+ */
+#include "../inc/MarlinConfig.h"
+
+#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+
+#if !PIN_EXISTS(CLOSED_LOOP_ENABLE) || !PIN_EXISTS(CLOSED_LOOP_MOVE_COMPLETE)
+  #error "CLOSED_LOOP_ENABLE_PIN and CLOSED_LOOP_MOVE_COMPLETE_PIN are required for EXTERNAL_CLOSED_LOOP_CONTROLLER."
+#endif
+
+#include "closedloop.h"
+
+void init_closedloop() {
+  OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, LOW);
+  SET_INPUT_PULLUP(CLOSED_LOOP_MOVE_COMPLETE_PIN);
+}
+
+void set_closedloop(const byte val) {
+  OUT_WRITE(CLOSED_LOOP_ENABLE_PIN, val);
+}
+
+#endif // EXTERNAL_CLOSED_LOOP_CONTROLLER
diff --git a/Marlin/src/feature/closedloop.h b/Marlin/src/feature/closedloop.h
new file mode 100644
index 0000000000000000000000000000000000000000..84cec36fe6c241d38aa17a5013f91322c911b733
--- /dev/null
+++ b/Marlin/src/feature/closedloop.h
@@ -0,0 +1,25 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * 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/>.
+ *
+ */
+#pragma once
+
+void init_closedloop();
+void set_closedloop(const byte val);
diff --git a/Marlin/src/gcode/calibrate/M12.cpp b/Marlin/src/gcode/calibrate/M12.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4b75e71bda58008a4b88a674125029a844d9e30
--- /dev/null
+++ b/Marlin/src/gcode/calibrate/M12.cpp
@@ -0,0 +1,36 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * Based on Sprinter and grbl.
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
+ *
+ * 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/>.
+ *
+ */
+#include "../../inc/MarlinConfigPre.h"
+
+#if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+
+#include "../gcode.h"
+#include "../../module/planner.h"
+#include "../../feature/closedloop.h"
+
+void GcodeSuite::M12() {
+  planner.synchronize();
+  if (parser.seenval('S'))
+    set_closedloop(parser.value_int()); // Force a CLC set
+}
+
+#endif
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 6682cfbeb94a072fcb71ddbea2492a132e7d5b96..063f32999f62fa8f606b25b8493358dc356d7b16 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -292,6 +292,10 @@ void GcodeSuite::process_parsed_command(
         case 5: M5(); break;                                      // M5 - turn spindle/laser off
       #endif
 
+      #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+        case 12: M12(); break;                                    // M12: Synchronize and optionally force a CLC set
+      #endif
+
       case 17: M17(); break;                                      // M17: Enable all stepper motors
 
       #if ENABLED(SDSUPPORT)
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index cb9e03b58f49794bfe1a3741a230853c9e9c375e..36d8fc3fc34db75b0074431c3a90a53964d8f884 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -76,6 +76,7 @@
  * M3   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to clockwise
  * M4   - Turn laser/spindle on, set spindle/laser speed/power, set rotation to counter-clockwise
  * M5   - Turn laser/spindle off
+ * M12  - Set up closed loop control system. More features coming soon. (Requires EXTERNAL_CLOSED_LOOP_CONTROLLER)
  * M17  - Enable/Power all stepper motors
  * M18  - Disable all stepper motors; same as M84
  * M20  - List SD card. (Requires SDSUPPORT)
@@ -438,6 +439,10 @@ private:
     static void M5();
   #endif
 
+  #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+    static void M12();
+  #endif
+
   static void M17();
 
   static void M18_M84();
diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp
index 43f7a40a41f4589dc0f57db08e6eaea2dbf730e0..4db6e58d4879e105458cf66dbb627a1c5c1b3801 100644
--- a/Marlin/src/module/planner.cpp
+++ b/Marlin/src/module/planner.cpp
@@ -1539,7 +1539,14 @@ float Planner::get_axis_position_mm(const AxisEnum axis) {
 /**
  * Block until all buffered steps are executed / cleaned
  */
-void Planner::synchronize() { while (has_blocks_queued() || cleaning_buffer_counter) idle(); }
+void Planner::synchronize() {
+  while (
+    has_blocks_queued() || cleaning_buffer_counter
+    #if ENABLED(EXTERNAL_CLOSED_LOOP_CONTROLLER)
+      || !READ(CLOSED_LOOP_MOVE_COMPLETE_PIN)
+    #endif
+  ) idle();
+}
 
 /**
  * Planner::_buffer_steps