diff --git a/Marlin/printcounter.cpp b/Marlin/printcounter.cpp
index a8da87d3304a9c2f90d2b1d8112e242cce79eb05..f2999fb0442cf9cf9e3f5949a56e7311fc7ff6c8 100644
--- a/Marlin/printcounter.cpp
+++ b/Marlin/printcounter.cpp
@@ -24,7 +24,112 @@
 #include "printcounter.h"
 #include <avr/eeprom.h>
 
-PrintCounter::PrintCounter(): super() {}
+PrintCounter::PrintCounter(): super() {
+  this->loadStats();
+}
+
+bool PrintCounter::isLoaded() {
+  return this->loaded;
+}
+
+void PrintCounter::initStats() {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("initStats"));
+  #endif
+
+  this->loaded = true;
+  this->data = {
+    0, 0, 0, 0
+  };
+
+  this->saveStats();
+  eeprom_write_byte((uint8_t*) this->addr, 0x16);
+}
+
+void PrintCounter::loadStats() {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("loadStats"));
+  #endif
+
+  uint16_t addr = this->addr;
+
+  // Checks if the EEPROM block is initialized
+  if (eeprom_read_byte((uint8_t*) addr) != 0x16) this->initStats();
+
+  else {
+    // Skip the magic header byte
+    addr += sizeof(uint8_t);
+
+    // @todo This section will need rewrite once the ConfigurationStore
+    // and/or PersistentStorage object comes along.
+    this->data.totalPrints = eeprom_read_word((uint16_t*) addr);
+    addr += sizeof(uint16_t);
+
+    this->data.finishedPrints = eeprom_read_word((uint16_t*) addr);
+    addr += sizeof(uint16_t);
+
+    this->data.printTime = eeprom_read_dword((uint32_t*) addr);
+    addr += sizeof(uint32_t);
+
+    this->data.longestPrint = eeprom_read_dword((uint32_t*) addr);
+  }
+
+  this->loaded = true;
+}
+
+void PrintCounter::saveStats() {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("saveStats"));
+  #endif
+
+  // Refuses to save data is object is not loaded
+  if (!this->isLoaded()) return;
+
+  // Skip the magic header byte
+  uint16_t addr = this->addr + sizeof(uint8_t);
+
+  // @todo This section will need rewrite once the ConfigurationStore
+  // and/or PersistentStorage object comes along.
+  eeprom_write_word ((uint16_t*) addr, this->data.totalPrints);
+  addr += sizeof(uint16_t);
+
+  eeprom_write_word ((uint16_t*) addr, this->data.finishedPrints);
+  addr += sizeof(uint16_t);
+
+  eeprom_write_dword((uint32_t*) addr, this->data.printTime);
+  addr += sizeof(uint32_t);
+
+  eeprom_write_dword((uint32_t*) addr, this->data.longestPrint);
+}
+
+void PrintCounter::showStats() {
+  SERIAL_ECHOPGM("Print statistics: Total: ");
+  SERIAL_ECHO(this->data.totalPrints);
+
+  SERIAL_ECHOPGM(", Finished: ");
+  SERIAL_ECHO(this->data.finishedPrints);
+
+  SERIAL_ECHOPGM(", Failed: ");
+  SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints);
+
+  uint32_t t = this->data.printTime /60;
+  SERIAL_ECHOPGM(", Total print time: ");
+  SERIAL_ECHO(t / 60);
+
+  SERIAL_ECHOPGM("h ");
+  SERIAL_ECHO(t % 60);
+
+  SERIAL_ECHOPGM("min");
+
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    SERIAL_ECHOPGM(" (");
+    SERIAL_ECHO(this->data.printTime);
+    SERIAL_ECHOPGM(")");
+  #endif
+
+  // @todo longestPrint missing implementation
+  SERIAL_EOL;
+}
 
 void PrintCounter::tick() {
   if (!this->isRunning()) return;
@@ -38,9 +143,14 @@ void PrintCounter::tick() {
   const static uint16_t i = this->updateInterval * 1000;
 
   if (now - update_before >= i) {
-    //this->addToTimeCounter((uint16_t) (now - update_before) / 1000);
+    #if ENABLED(DEBUG_PRINTCOUNTER)
+      PrintCounter::debug(PSTR("tick"));
+    #endif
+
+    uint16_t t = this->duration();;
+    this->data.printTime += t - this->lastUpdate;
+    this->lastUpdate = t;
     update_before = now;
-    PrintCounter::debug(PSTR("tick1"));
   }
 
   // Trying to get the amount of calculations down to the bare min
@@ -48,52 +158,37 @@ void PrintCounter::tick() {
 
   if (now - eeprom_before >= j) {
     eeprom_before = now;
-    this->save();
+    this->saveStats();
   }
 }
 
-void PrintCounter::load() {
-  uint16_t pos = this->addr;
-
-  this->data.successPrints= eeprom_read_word ((uint16_t*) pos);
-  this->data.failedPrints = eeprom_read_word ((uint16_t*) pos);
-  this->data.printTime    = eeprom_read_dword((uint32_t*) pos);
-  this->data.longestPrint = eeprom_read_dword((uint32_t*) pos);
-
-  SERIAL_ECHOPGM("successPrints: ");
-  SERIAL_ECHOLN(this->data.successPrints);
-
-  SERIAL_ECHOPGM("failedPrints: ");
-  SERIAL_ECHOLN(this->data.failedPrints);
-
-  SERIAL_ECHOPGM("printTime: ");
-  SERIAL_ECHOLN(this->data.printTime);
+void PrintCounter::start() {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("start"));
+  #endif
 
-  SERIAL_ECHOPGM("longestPrint: ");
-  SERIAL_ECHOLN(this->data.longestPrint);
+  if (!this->isPaused()) this->data.totalPrints++;
+  super::start();
 }
 
-void PrintCounter::save() {
+void PrintCounter::stop() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("save"));
+    PrintCounter::debug(PSTR("stop"));
   #endif
 
-  uint16_t pos = this->addr;
-
-  eeprom_write_word ((uint16_t*) pos, this->data.successPrints);
-  eeprom_write_word ((uint16_t*) pos, this->data.failedPrints);
-  eeprom_write_dword((uint32_t*) pos, this->data.printTime);
-  eeprom_write_dword((uint32_t*) pos, this->data.longestPrint);
+  super::stop();
+  this->data.finishedPrints++;
+  this->data.printTime += this->duration() - this->lastUpdate;
+  this->saveStats();
 }
 
-void PrintCounter::start() {
-  super::start();
-  this->load();
-}
+void PrintCounter::reset() {
+  #if ENABLED(DEBUG_PRINTCOUNTER)
+    PrintCounter::debug(PSTR("stop"));
+  #endif
 
-void PrintCounter::stop() {
-  super::stop();
-  this->save();
+  this->lastUpdate = 0;
+  super::reset();
 }
 
 #if ENABLED(DEBUG_PRINTCOUNTER)
diff --git a/Marlin/printcounter.h b/Marlin/printcounter.h
index 99d5b207b6c97f37f08dc96eda2ec67f3fd62fec..e2410104b0ed22356a7819100ecfeff72aa7d768 100644
--- a/Marlin/printcounter.h
+++ b/Marlin/printcounter.h
@@ -29,11 +29,12 @@
 // Print debug messages with M111 S2
 #define DEBUG_PRINTCOUNTER
 
-struct printStatistics {  // 12 bytes
-  uint16_t successPrints; // Total number of prints
-  uint16_t failedPrints;  // Total number of aborted prints - not in use
-  uint32_t printTime;     // Total time printing
-  uint32_t longestPrint;  // Longest print job - not in use
+struct printStatistics {    // 13 bytes
+  //uint8_t  magic;         // Magic header, it will always be 0x16
+  uint16_t totalPrints;     // Number of prints
+  uint16_t finishedPrints;  // Number of complete prints
+  uint32_t printTime;       // Total printing time
+  uint32_t longestPrint;    // Longest print job - not in use
 };
 
 class PrintCounter: public Stopwatch {
@@ -42,11 +43,19 @@ class PrintCounter: public Stopwatch {
 
     printStatistics data;
 
+    /**
+     * @brief Timestamp of the last update
+     * @details Stores the timestamp of the last data.pritnTime update, when the
+     * print job finishes, this will be used to calculate the exact time elapsed,
+     * this is required due to the updateInterval cycle.
+     */
+    uint16_t lastUpdate;
+
     /**
      * @brief EEPROM address
      * @details Defines the start offset address where the data is stored.
      */
-    const uint16_t addr = 60;
+    const uint16_t addr = 50;
 
     /**
      * @brief Interval in seconds between counter updates
@@ -54,7 +63,7 @@ class PrintCounter: public Stopwatch {
      * accumulator update. This is different from the EEPROM save interval
      * which is user defined at the Configuration.h file.
      */
-    const uint16_t updateInterval = 2;
+    const uint16_t updateInterval = 10;
 
     /**
      * @brief Interval in seconds between EEPROM saves
@@ -64,20 +73,65 @@ class PrintCounter: public Stopwatch {
      */
     const uint16_t saveInterval = PRINTCOUNTER_SAVE_INTERVAL;
 
+    /**
+     * @brief Stats were loaded from EERPROM
+     * @details If set to true it indicates if the statistical data was already
+     * loaded from the EEPROM.
+     */
+    bool loaded = false;
+
   public:
     /**
      * @brief Class constructor
      */
     PrintCounter();
 
+    /**
+     * @brief Checks if Print Statistics has been loaded
+     * @details Returns true if the statistical data has been loaded.
+     * @return bool
+     */
+    bool isLoaded();
+
+    /**
+     * @brief Resets the Print Statistics
+     * @details Resets the statistics to zero and saves them to EEPROM creating
+     * also the magic header.
+     */
+    void initStats();
+
+    /**
+     * @brief Loads the Print Statistics
+     * @details Loads the statistics from EEPROM
+     */
+    void loadStats();
+
+    /**
+     * @brief Saves the Print Statistics
+     * @details Saves the statistics to EEPROM
+     */
+    void saveStats();
+
+    /**
+     * @brief Serial output the Print Statistics
+     * @details This function may change in the future, for now it directly
+     * prints the statistical data to serial.
+     */
+    void showStats();
+
+    /**
+     * @brief Loop function
+     * @details This function should be called at loop, it will take care of
+     * periodically save the statistical data to EEPROM and do time keeping.
+     */
     void tick();
-    void save();
-    void load();
-    void addToTimeCounter(uint16_t const &minutes);
-    void addToPrintCounter(uint8_t const &prints);
 
+    /**
+     * The following functions are being overridden
+     */
     void start();
     void stop();
+    void reset();
 
     #if ENABLED(DEBUG_PRINTCOUNTER)