diff --git a/Marlin/src/HAL/shared/eeprom_if_i2c.cpp b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp
index da70af2772..299bc34c49 100644
--- a/Marlin/src/HAL/shared/eeprom_if_i2c.cpp
+++ b/Marlin/src/HAL/shared/eeprom_if_i2c.cpp
@@ -51,6 +51,18 @@ void eeprom_init() {
 
 static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRESS);
 
+void _beginTransmission(const uint16_t memoryAddress) {
+  if (MARLIN_EEPROM_SIZE > 0x4000) {  // Use two-byte addressing for EEPROMs >16kb
+    Wire.beginTransmission(eeprom_device_address);
+    Wire.write(memoryAddress >> 8);   // Address High Byte
+  }
+  else {
+    const uint8_t addr = eeprom_device_address | byte((memoryAddress >> 8) & 0x07);
+    Wire.beginTransmission(addr);
+  }
+  Wire.write(memoryAddress & 0xFF);   // Address Low Byte (or only byte for chips <= 16Kb like 24C02/04/08/16)
+}
+
 // ------------------------
 // Public functions
 // ------------------------
@@ -58,9 +70,7 @@ static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRE
 void eeprom_write_byte(uint8_t *pos, unsigned char value) {
   const unsigned eeprom_address = (unsigned)pos;
 
-  Wire.beginTransmission(eeprom_device_address);
-  Wire.write(int(eeprom_address >> 8));   // MSB
-  Wire.write(int(eeprom_address & 0xFF)); // LSB
+  _beginTransmission(eeprom_address);
   Wire.write(value);
   Wire.endTransmission();
 
@@ -72,11 +82,12 @@ void eeprom_write_byte(uint8_t *pos, unsigned char value) {
 uint8_t eeprom_read_byte(uint8_t *pos) {
   const unsigned eeprom_address = (unsigned)pos;
 
-  Wire.beginTransmission(eeprom_device_address);
-  Wire.write(int(eeprom_address >> 8));   // MSB
-  Wire.write(int(eeprom_address & 0xFF)); // LSB
+  _beginTransmission(eeprom_address);
   Wire.endTransmission();
-  Wire.requestFrom(eeprom_device_address, (byte)1);
+
+  // For EEPROMs <=16Kb the lower address bits are used for 2Kb page address
+  const int addr = eeprom_device_address | (MARLIN_EEPROM_SIZE <= 0x4000 ? byte((eeprom_address >> 8) & 0x07) : byte(0));
+  Wire.requestFrom(addr, byte(1));
   return Wire.available() ? Wire.read() : 0xFF;
 }