diff --git a/Documentation/GCodes.md b/Documentation/GCodes.md
index 253fb7fc81..fde8435932 100644
--- a/Documentation/GCodes.md
+++ b/Documentation/GCodes.md
@@ -101,3 +101,25 @@
 *  M908 - Control digital trimpot directly.
 *  M928 - Start SD logging (M928 filename.g) - ended by M29
 *  M999 - Restart after being stopped by error
+
+# Comments
+
+Comments start at a `;` (semicolon) and end with the end of the line:
+
+    N3 T0*57 ; This is a comment
+    N4 G92 E0*67
+    ; So is this
+    N5 G28*22
+
+(example taken from the [RepRap wiki](http://reprap.org/wiki/Gcode#Comments))
+
+If you need to use a literal `;` somewhere (for example within `M117`), you can escape semicolons with a `\`
+(backslash):
+
+     M117 Hello \;)
+
+`\` can also be used to escape `\` itself, if you need a literal `\` in front of a `;`:
+
+    M117 backslash: \\;and a comment
+
+Please note that hosts should strip any comments before sending GCODE to the printer in order to save bandwidth.
\ No newline at end of file
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index b2ebbbe518..ca1af6038c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -730,103 +730,113 @@ void get_command()
     serial_char = MYSERIAL.read();
     if(serial_char == '\n' ||
        serial_char == '\r' ||
-       (serial_char == ':' && comment_mode == false) ||
        serial_count >= (MAX_CMD_SIZE - 1) )
     {
-      if(!serial_count) { //if empty line
-        comment_mode = false; //for new command
+      // end of line == end of comment
+      comment_mode = false;
+
+      if(!serial_count) {
+        // short cut for empty lines
         return;
       }
       cmdbuffer[bufindw][serial_count] = 0; //terminate string
-      if(!comment_mode){
-        comment_mode = false; //for new command
-        fromsd[bufindw] = false;
-        if(strchr(cmdbuffer[bufindw], 'N') != NULL)
+
+      fromsd[bufindw] = false;
+      if(strchr(cmdbuffer[bufindw], 'N') != NULL)
+      {
+        strchr_pointer = strchr(cmdbuffer[bufindw], 'N');
+        gcode_N = (strtol(strchr_pointer + 1, NULL, 10));
+        if(gcode_N != gcode_LastN+1 && (strstr_P(cmdbuffer[bufindw], PSTR("M110")) == NULL) ) {
+          SERIAL_ERROR_START;
+          SERIAL_ERRORPGM(MSG_ERR_LINE_NO);
+          SERIAL_ERRORLN(gcode_LastN);
+          //Serial.println(gcode_N);
+          FlushSerialRequestResend();
+          serial_count = 0;
+          return;
+        }
+
+        if(strchr(cmdbuffer[bufindw], '*') != NULL)
         {
-          strchr_pointer = strchr(cmdbuffer[bufindw], 'N');
-          gcode_N = (strtol(strchr_pointer + 1, NULL, 10));
-          if(gcode_N != gcode_LastN+1 && (strstr_P(cmdbuffer[bufindw], PSTR("M110")) == NULL) ) {
-            SERIAL_ERROR_START;
-            SERIAL_ERRORPGM(MSG_ERR_LINE_NO);
-            SERIAL_ERRORLN(gcode_LastN);
-            //Serial.println(gcode_N);
-            FlushSerialRequestResend();
-            serial_count = 0;
-            return;
-          }
+          byte checksum = 0;
+          byte count = 0;
+          while(cmdbuffer[bufindw][count] != '*') checksum = checksum^cmdbuffer[bufindw][count++];
+          strchr_pointer = strchr(cmdbuffer[bufindw], '*');
 
-          if(strchr(cmdbuffer[bufindw], '*') != NULL)
-          {
-            byte checksum = 0;
-            byte count = 0;
-            while(cmdbuffer[bufindw][count] != '*') checksum = checksum^cmdbuffer[bufindw][count++];
-            strchr_pointer = strchr(cmdbuffer[bufindw], '*');
-
-            if( (int)(strtod(strchr_pointer + 1, NULL)) != checksum) {
-              SERIAL_ERROR_START;
-              SERIAL_ERRORPGM(MSG_ERR_CHECKSUM_MISMATCH);
-              SERIAL_ERRORLN(gcode_LastN);
-              FlushSerialRequestResend();
-              serial_count = 0;
-              return;
-            }
-            //if no errors, continue parsing
-          }
-          else
-          {
+          if( (int)(strtod(strchr_pointer + 1, NULL)) != checksum) {
             SERIAL_ERROR_START;
-            SERIAL_ERRORPGM(MSG_ERR_NO_CHECKSUM);
+            SERIAL_ERRORPGM(MSG_ERR_CHECKSUM_MISMATCH);
             SERIAL_ERRORLN(gcode_LastN);
             FlushSerialRequestResend();
             serial_count = 0;
             return;
           }
-
-          gcode_LastN = gcode_N;
           //if no errors, continue parsing
         }
-        else  // if we don't receive 'N' but still see '*'
+        else
         {
-          if((strchr(cmdbuffer[bufindw], '*') != NULL))
-          {
-            SERIAL_ERROR_START;
-            SERIAL_ERRORPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
-            SERIAL_ERRORLN(gcode_LastN);
-            serial_count = 0;
-            return;
-          }
-        }
-        if((strchr(cmdbuffer[bufindw], 'G') != NULL)){
-          strchr_pointer = strchr(cmdbuffer[bufindw], 'G');
-          switch((int)((strtod(strchr_pointer + 1, NULL)))){
-          case 0:
-          case 1:
-          case 2:
-          case 3:
-            if (Stopped == true) {
-              SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
-              LCD_MESSAGEPGM(MSG_STOPPED);
-            }
-            break;
-          default:
-            break;
-          }
-
+          SERIAL_ERROR_START;
+          SERIAL_ERRORPGM(MSG_ERR_NO_CHECKSUM);
+          SERIAL_ERRORLN(gcode_LastN);
+          FlushSerialRequestResend();
+          serial_count = 0;
+          return;
         }
 
-        //If command was e-stop process now
-        if(strcmp(cmdbuffer[bufindw], "M112") == 0)
-          kill();
-        
-        bufindw = (bufindw + 1)%BUFSIZE;
-        buflen += 1;
+        gcode_LastN = gcode_N;
+        //if no errors, continue parsing
       }
+      else  // if we don't receive 'N' but still see '*'
+      {
+        if((strchr(cmdbuffer[bufindw], '*') != NULL))
+        {
+          SERIAL_ERROR_START;
+          SERIAL_ERRORPGM(MSG_ERR_NO_LINENUMBER_WITH_CHECKSUM);
+          SERIAL_ERRORLN(gcode_LastN);
+          serial_count = 0;
+          return;
+        }
+      }
+      if((strchr(cmdbuffer[bufindw], 'G') != NULL)){
+        strchr_pointer = strchr(cmdbuffer[bufindw], 'G');
+        switch((int)((strtod(strchr_pointer + 1, NULL)))){
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+          if (Stopped == true) {
+            SERIAL_ERRORLNPGM(MSG_ERR_STOPPED);
+            LCD_MESSAGEPGM(MSG_STOPPED);
+          }
+          break;
+        default:
+          break;
+        }
+
+      }
+
+      //If command was e-stop process now
+      if(strcmp(cmdbuffer[bufindw], "M112") == 0)
+        kill();
+
+      bufindw = (bufindw + 1)%BUFSIZE;
+      buflen += 1;
+
       serial_count = 0; //clear buffer
     }
-    else
-    {
-      if(serial_char == ';') comment_mode = true;
-      if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char;
+    else if(serial_char == '\\') {  //Handle escapes
+       
+        if(MYSERIAL.available() > 0  && buflen < BUFSIZE) {
+            // if we have one more character, copy it over
+            serial_char = MYSERIAL.read();
+            cmdbuffer[bufindw][serial_count++] = serial_char;
+        }
+
+        //otherwise do nothing        
+    }
+    else { // its not a newline, carriage return or escape char
+        if(serial_char == ';') comment_mode = true;
+        if(!comment_mode) cmdbuffer[bufindw][serial_count++] = serial_char;
     }
   }
   #ifdef SDSUPPORT