diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index a6846bc0bcf7191704cbadf96824500d0985bcd5..14c427be475e0fce637c8855b7d47b1576ebe72c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2564,8 +2564,14 @@ void gcode_get_destination() {
     else
       destination[i] = current_position[i];
   }
+
   if (code_seen('F') && code_value_linear_units() > 0.0)
     feedrate = code_value_linear_units();
+
+  #if ENABLED(PRINTCOUNTER)
+    if(!DEBUGGING(DRYRUN))
+      print_job_timer.incFilamentUsed(destination[E_AXIS] - current_position[E_AXIS]);
+  #endif
 }
 
 void unknown_command_error() {
diff --git a/Marlin/language.h b/Marlin/language.h
index 2e74e42d2773643aa491ab53d3f7babd70dc495a..093368333885869c36ea46cb35fda01bea4225ee 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -119,6 +119,7 @@
 #define MSG_PLANNER_BUFFER_BYTES            "  PlannerBufferBytes: "
 #define MSG_OK                              "ok"
 #define MSG_WAIT                            "wait"
+#define MSG_STATS                           "Stats: "
 #define MSG_FILE_SAVED                      "Done saving file."
 #define MSG_ERR_LINE_NO                     "Line Number is not Last Line Number+1, Last Line: "
 #define MSG_ERR_CHECKSUM_MISMATCH           "checksum mismatch, Last Line: "
diff --git a/Marlin/printcounter.cpp b/Marlin/printcounter.cpp
index 6e875fabcf8441b9b853a98e26abf459f72e7fef..489503c3a9daac26125c9cc0379089eb99ef1ef4 100644
--- a/Marlin/printcounter.cpp
+++ b/Marlin/printcounter.cpp
@@ -41,13 +41,25 @@ bool PrintCounter::isLoaded() {
   return this->loaded;
 }
 
+void PrintCounter::incFilamentUsed(double const &amount) {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("incFilamentUsed"));
+  #endif
+
+  // Refuses to update data if object is not loaded
+  if (!this->isLoaded()) return;
+
+  this->data.filamentUsed += amount; // mm
+}
+
+
 void PrintCounter::initStats() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
     PrintCounter::debug(PSTR("initStats"));
   #endif
 
   this->loaded = true;
-  this->data = { 0, 0, 0, 0 };
+  this->data = { 0, 0, 0, 0, 0.0 };
 
   this->saveStats();
   eeprom_write_byte((uint8_t *) this->address, 0x16);
@@ -60,7 +72,8 @@ void PrintCounter::loadStats() {
 
   // Checks if the EEPROM block is initialized
   if (eeprom_read_byte((uint8_t *) this->address) != 0x16) this->initStats();
-  else eeprom_read_block(&this->data, (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+  else eeprom_read_block(&this->data,
+    (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
 
   this->loaded = true;
 }
@@ -70,31 +83,40 @@ void PrintCounter::saveStats() {
     PrintCounter::debug(PSTR("saveStats"));
   #endif
 
-  // Refuses to save data is object is not loaded
+  // Refuses to save data if object is not loaded
   if (!this->isLoaded()) return;
 
   // Saves the struct to EEPROM
-  eeprom_update_block(&this->data, (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+  eeprom_update_block(&this->data,
+    (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
 }
 
 void PrintCounter::showStats() {
-  SERIAL_ECHOPGM("Print statistics: Total: ");
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("Prints: ");
   SERIAL_ECHO(this->data.totalPrints);
 
   SERIAL_ECHOPGM(", Finished: ");
   SERIAL_ECHO(this->data.finishedPrints);
 
-  SERIAL_ECHOPGM(", Failed: ");
+  SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter
   SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints
-    - ((this->isRunning() || this->isPaused()) ? 1 : 0)); // Removes 1 from failures with an active counter
+    - ((this->isRunning() || this->isPaused()) ? 1 : 0));
+
+  SERIAL_EOL;
+  SERIAL_PROTOCOLPGM(MSG_STATS);
 
-  millis_t t = this->data.printTime / 60; // minutes from seconds
-  SERIAL_ECHOPGM(", Total print time: ");
-  SERIAL_ECHO(t / 60); // hours
+  uint32_t t = this->data.printTime / 60;
+  SERIAL_ECHOPGM("Total time: ");
 
+  SERIAL_ECHO(t / 60 / 24);
+  SERIAL_ECHOPGM("d ");
+
+  SERIAL_ECHO((t / 60) % 24);
   SERIAL_ECHOPGM("h ");
-  SERIAL_ECHO(t % 60); // minutes
 
+  SERIAL_ECHO(t % 60);
   SERIAL_ECHOPGM("min");
 
   #if ENABLED(DEBUG_PRINTCOUNTER)
@@ -103,34 +125,58 @@ void PrintCounter::showStats() {
     SERIAL_ECHOPGM(")");
   #endif
 
-  // @todo longestPrint missing implementation
+  uint32_t l = this->data.longestPrint / 60;
+  SERIAL_ECHOPGM(", Longest job: ");
+
+  SERIAL_ECHO(l / 60 / 24);
+  SERIAL_ECHOPGM("d ");
+
+  SERIAL_ECHO((l / 60) % 24);
+  SERIAL_ECHOPGM("h ");
+
+  SERIAL_ECHO(l % 60);
+  SERIAL_ECHOPGM("min");
+
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    SERIAL_ECHOPGM(" (");
+    SERIAL_ECHO(this->data.longestPrint);
+    SERIAL_ECHOPGM(")");
+  #endif
+
+  SERIAL_EOL;
+  SERIAL_PROTOCOLPGM(MSG_STATS);
+
+  SERIAL_ECHOPGM("Filament used: ");
+  SERIAL_ECHO(this->data.filamentUsed / 1000);
+  SERIAL_ECHOPGM("m");
+
   SERIAL_EOL;
 }
 
 void PrintCounter::tick() {
   if (!this->isRunning()) return;
 
-  static millis_t update_before = millis(),
-                  eeprom_before = millis();
+  static uint32_t update_last = millis(),
+                  eeprom_last = millis();
 
   millis_t now = millis();
 
   // Trying to get the amount of calculations down to the bare min
   const static uint16_t i = this->updateInterval * 1000;
 
-  if (now - update_before >= i) {
+  if (now - update_last >= i) {
     #if ENABLED(DEBUG_PRINTCOUNTER)
       PrintCounter::debug(PSTR("tick"));
     #endif
 
     this->data.printTime += this->deltaDuration();
-    update_before = now;
+    update_last = now;
   }
 
   // Trying to get the amount of calculations down to the bare min
   const static millis_t j = this->saveInterval * 1000;
-  if (now - eeprom_before >= j) {
-    eeprom_before = now;
+  if (now - eeprom_last >= j) {
+    eeprom_last = now;
     this->saveStats();
   }
 }
@@ -162,6 +208,10 @@ bool PrintCounter::stop() {
   if (super::stop()) {
     this->data.finishedPrints++;
     this->data.printTime += this->deltaDuration();
+
+    if (this->duration() > this->data.longestPrint)
+      this->data.longestPrint = this->duration();
+
     this->saveStats();
     return true;
   }
diff --git a/Marlin/printcounter.h b/Marlin/printcounter.h
index c7742a07be4238a5b1f1f9ef51f68417a8851a7e..0e9d06f45e49d9dabeabab5d15db80a06e924297 100644
--- a/Marlin/printcounter.h
+++ b/Marlin/printcounter.h
@@ -24,6 +24,7 @@
 #define PRINTCOUNTER_H
 
 #include "macros.h"
+#include "language.h"
 #include "stopwatch.h"
 #include <avr/eeprom.h>
 
@@ -35,8 +36,9 @@ struct printStatistics {    // 13 bytes
   //const uint8_t magic;    // Magic header, it will always be 0x16
   uint16_t totalPrints;     // Number of prints
   uint16_t finishedPrints;  // Number of complete prints
-  millis_t printTime;       // Total printing time
-  millis_t longestPrint;    // Longest print job - not in use
+  uint32_t printTime;       // Accumulated printing time
+  uint32_t longestPrint;    // Longest successfull print job
+  double   filamentUsed;    // Accumulated filament consumed in mm
 };
 
 class PrintCounter: public Stopwatch {
@@ -105,6 +107,14 @@ class PrintCounter: public Stopwatch {
      */
     bool isLoaded();
 
+    /**
+     * @brief Increments the total filament used
+     * @details The total filament used counter will be incremented by "amount".
+     *
+     * @param amount The amount of filament used in mm
+     */
+    void incFilamentUsed(double const &amount);
+
     /**
      * @brief Resets the Print Statistics
      * @details Resets the statistics to zero and saves them to EEPROM creating