diff --git a/avr-libc/devtools/Device.am b/avr-libc/devtools/Device.am
index 3279b27..a5e2df2 100644
--- a/avr-libc/devtools/Device.am
+++ b/avr-libc/devtools/Device.am
@@ -83,7 +83,8 @@ nodist_libdev_a_SOURCES = $(eeprom_asm_sources)
 else
 # avr-gcc > 5.1.0 expects device library as lib<device name>.a
 avr_LIBRARIES = lib<<dev>>.a
-nodist_lib<<dev>>_a_SOURCES = $(eeprom_asm_sources)
+nodist_lib<<dev>>_a_SOURCES = $(eeprom_c_sources) $(dev_c_sources) \
+	$(eeprom_asm_sources) $(dev_asm_sources)
 endif
 endif
 
diff --git a/avr-libc/devtools/gen-avr-lib-tree.sh b/avr-libc/devtools/gen-avr-lib-tree.sh
index b3e5498..b942904 100755
--- a/avr-libc/devtools/gen-avr-lib-tree.sh
+++ b/avr-libc/devtools/gen-avr-lib-tree.sh
@@ -472,7 +472,18 @@ do
 		    -e "s/<<crt_cflags>>/$crt_cflags/g" \
 		    -e "s/<<crt_asflags>>/$crt_asflags/g"  \
 		    -e "s/<<install_dir>>/$inst_dir_masked/g" $dev/Makefile.am \
-		    > $dev/tempfile && mv -f $dev/tempfile $dev/Makefile.am
+		    > $dev/tempfile
+
+		case "$dev" in
+		  at90s1200|attiny11|attiny12|attiny15|attiny28)
+			sed -e "s/\$(eeprom_c_sources)//g" \
+				-e "s/\$(dev_c_sources)//g" $dev/tempfile \
+			> $dev/tempfile_2 && mv -f $dev/tempfile_2 $dev/Makefile.am
+			;;
+		  *)
+			mv -f $dev/tempfile $dev/Makefile.am
+			;;
+		esac
 
 		DEV_SUBDIRS="$DEV_SUBDIRS $dev"
 	done
diff --git a/avr-libc/include/avr/cpufunc.h b/avr-libc/include/avr/cpufunc.h
index 45533fa..fd8d9cc 100644
--- a/avr-libc/include/avr/cpufunc.h
+++ b/avr-libc/include/avr/cpufunc.h
@@ -80,4 +80,12 @@
 #define _MemoryBarrier() __asm__ __volatile__("":::"memory")
 #endif  /* __DOXYGEN__ */
 
+/**
+   \ingroup avr_cpufunc
+
+   Write \a __value to Configuration Change Protected (CCP) IO register
+   at \a __ioaddr.
+ */
+void ccp_write_io (uint8_t *__ioaddr, uint8_t __value);
+
 #endif /* _AVR_CPUFUNC_H_ */
diff --git a/avr-libc/libc/misc/Files.am b/avr-libc/libc/misc/Files.am
index 156a96e..73c050b 100644
--- a/avr-libc/libc/misc/Files.am
+++ b/avr-libc/libc/misc/Files.am
@@ -31,6 +31,9 @@
 
 misc_a_c_sources =
 
+eeprom_c_sources = \
+	eewr_block_xmega.c
+
 eeprom_asm_sources = \
 	eerd_block.S \
 	eerd_byte.S \
@@ -45,6 +48,11 @@ eeprom_asm_sources = \
 	eewr_dword.S \
 	eewr_word.S
 
+dev_c_sources =
+
+dev_asm_sources = \
+	ccp_write.S
+
 misc_a_asm_sources = \
 	itoa.S \
 	itoa_ncheck.S \
diff --git a/avr-libc/libc/misc/Makefile.am b/avr-libc/libc/misc/Makefile.am
index 6e9a713..d80f388 100644
--- a/avr-libc/libc/misc/Makefile.am
+++ b/avr-libc/libc/misc/Makefile.am
@@ -32,7 +32,10 @@
 include $(top_srcdir)/libc/misc/Files.am
 
 EXTRA_DIST = \
+	$(eeprom_c_sources) \
 	$(eeprom_asm_sources) \
+	$(dev_c_sources) \
+	$(dev_asm_sources) \
 	$(misc_a_asm_sources) \
 	$(misc_a_c_sources) \
 	$(misc_a_extra_dist)
diff --git a/avr-libc/libc/misc/ccp_write.S b/avr-libc/libc/misc/ccp_write.S
new file mode 100644
index 0000000..c1aa0c8
--- /dev/null
+++ b/avr-libc/libc/misc/ccp_write.S
@@ -0,0 +1,27 @@
+#ifndef __DOXYGEN__
+
+#include <avr/io.h>
+
+#if __AVR_XMEGA__
+
+# ifndef CCP_IOREG_gc
+#  define CCP_IOREG_gc	0xD8	/* IO Register Protection	*/
+# endif
+
+#include "asmdef.h"
+
+/*  void ccp_write_io (uint8_t *__ioaddr, uint8_t __value)
+ */
+ENTRY	ccp_write_io
+	; r24,25 - __ioaddr
+	; r22    - __value
+	X_movw	r26, r24			; load io addr into X
+	ldi		r18, CCP_IOREG_gc	; load IO reg change protection signature
+	sts		CCP, r18
+	st		x, r22				; write __value to __ioaddr
+	ret
+ENDFUNC
+
+#endif  /* __AVR_XMEGA__ && CCP_IOREG_gc */ 
+#endif  /* !__DOXYGEN__ */
+
diff --git a/avr-libc/libc/misc/eewr_block.S b/avr-libc/libc/misc/eewr_block.S
index f68bf40..e30a6f4 100644
--- a/avr-libc/libc/misc/eewr_block.S
+++ b/avr-libc/libc/misc/eewr_block.S
@@ -34,13 +34,15 @@
 
 #if	E2END && __AVR_ARCH__ > 1
 
+/* Skip for Xmega with valid page size. Refer. eewr_block_xmega.c.  */
+#if !(__AVR_XMEGA__ && defined (E2PAGESIZE) && (E2PAGESIZE))
+
 #include <avr/eeprom.h>
 #include "asmdef.h"
 #include "eedef.h"
 
 /* void eeprom_write_block (const void *sram, void *eepr, size_t n)
  */
-
 #define sram_lo	r24	/* SRAM address		*/
 #define eepr_lo	r22	/* EEPROM address	*/
 
@@ -71,6 +73,6 @@ ENTRY	eeprom_write_block
 	ret
 
 ENDFUNC
-
+#endif  /* All except __AVR_XMEGA__ && E2PAGESIZE */
 #endif	/* E2END && __AVR_ARCH__ > 1 */
 #endif	/* !__DOXYGEN__ */
diff --git a/avr-libc/libc/misc/eewr_block_xmega.c b/avr-libc/libc/misc/eewr_block_xmega.c
new file mode 100644
index 0000000..b84e3ed
--- /dev/null
+++ b/avr-libc/libc/misc/eewr_block_xmega.c
@@ -0,0 +1,82 @@
+/* $Id$ */
+#ifndef __DOXYGEN__
+
+#include <avr/io.h>
+
+#if E2END && __AVR_XMEGA__ && defined(E2PAGESIZE) && (E2PAGESIZE)
+
+#include <assert.h>
+#include "sectionname.h"
+#include <avr/eeprom.h>
+
+extern void ccp_write_io (volatile uint8_t *__ioaddr, uint8_t __value);
+
+ATTRIBUTE_CLIB_SECTION
+static void
+eeprom_write_page (const uint8_t *sram, uint16_t eeprom_addr,
+					uint8_t byte_position, uint8_t nbytes)
+{
+  assert (eeprom_addr <= (uint16_t)(E2END - nbytes));
+
+  uint8_t i = byte_position;
+  uint8_t data_index = 0;
+
+  /* Wait till nvm is ready.  */
+  do {
+  } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm);
+
+  while (data_index < nbytes)
+  {
+    do {
+    } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm);
+
+
+    #if defined (NVM_EEMAPEN_bm)
+    /* enable memory map.  */
+    NVM_CTRLB = NVM_CTRLB | NVM_EEMAPEN_bm;
+    #endif
+
+    /* Load byte into page buffer.  */
+    *((uint8_t*)MAPPED_EEPROM_START + i) = sram[data_index];
+
+    data_index++;
+    i++;
+
+    #if defined (NVM_EEMAPEN_bm)
+    /* disable memory map.  */
+    NVM_CTRLB = NVM_CTRLB & ~NVM_EEMAPEN_bm;
+    #endif
+  }
+
+  /* Load eeprom address.  */
+  #if defined (NVM_ADDR2)
+    NVM.ADDR2 = 0;
+  #endif
+  NVM.ADDR1 = ((eeprom_addr >> 8) & 0xff);
+  NVM.ADDR0 = ((eeprom_addr & 0xff));
+  /* Issue EEPROM erase and write command.  */
+  NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
+  ccp_write_io (&NVM.CTRLA, NVM_CMDEX_bm);
+}
+
+/* void eeprom_write_block (const void *sram, void *eeprom_addr, size_t length)
+ */
+ATTRIBUTE_CLIB_SECTION
+void eeprom_write_block (const void *sram, void *eeprom_addr, size_t length)
+{
+  while (length)
+  {
+    uint8_t byte_position = ((uint16_t)eeprom_addr & (E2PAGESIZE-1));
+    uint8_t nbytes = E2PAGESIZE - byte_position;
+    nbytes = nbytes > length ? length : nbytes;
+    eeprom_write_page ((uint8_t*)sram, (uint16_t)eeprom_addr,
+                       byte_position, nbytes);
+    sram = (uint8_t*)sram + nbytes;
+    eeprom_addr = (uint8_t*)eeprom_addr + nbytes;
+    length -= nbytes;
+  }
+}
+
+#endif  /* E2END && __AVR_XMEGA__ && E2PAGESIZE */
+#endif  /* !__DOXYGEN__ */
+
