diff --git a/plat/hisilicon/poplar/aarch64/platform_common.c b/plat/hisilicon/poplar/aarch64/platform_common.c
index 762bd84671b0d0d10c0e75f22cd1cf246bdcb8cc..549806505cb759ab38148a4cf9a4e19bd95d0004 100644
--- a/plat/hisilicon/poplar/aarch64/platform_common.c
+++ b/plat/hisilicon/poplar/aarch64/platform_common.c
@@ -29,10 +29,24 @@
 					TSP_SEC_MEM_SIZE,		\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
+#if LOAD_IMAGE_V2
+#ifdef SPD_opteed
+#define MAP_OPTEE_PAGEABLE	MAP_REGION_FLAT(		\
+				POPLAR_OPTEE_PAGEABLE_LOAD_BASE,	\
+				POPLAR_OPTEE_PAGEABLE_LOAD_SIZE,	\
+				MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+#endif
+
 static const mmap_region_t poplar_mmap[] = {
 	MAP_DDR,
 	MAP_DEVICE,
 	MAP_TSP_MEM,
+#if LOAD_IMAGE_V2
+#ifdef SPD_opteed
+	MAP_OPTEE_PAGEABLE,
+#endif
+#endif
 	{0}
 };
 
diff --git a/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c b/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
index 434f577ecd20052a465c850ad4317c508ab60e6c..c73ead8d759110629501bef6ff4f333b7ba0a569 100644
--- a/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
+++ b/plat/hisilicon/poplar/bl2_plat_mem_params_desc.c
@@ -99,6 +99,43 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 
 	    .next_handoff_image_id = BL33_IMAGE_ID,
 	},
+
+	/*
+	 * Fill BL32 external 1 related information.
+	 * A typical use for extra1 image is with OP-TEE where it is the pager image.
+	 */
+	{
+	    .image_id = BL32_EXTRA1_IMAGE_ID,
+
+	    SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+		    VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+	    SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+		    VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+	    .image_info.image_base = BL32_BASE,
+	    .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+	    .next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/*
+	 * Fill BL32 external 2 related information.
+	 * A typical use for extra2 image is with OP-TEE where it is the paged image.
+	 */
+	{
+	    .image_id = BL32_EXTRA2_IMAGE_ID,
+
+	    SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+		    VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+
+	    SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+		    VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+#ifdef SPD_opteed
+	    .image_info.image_base = POPLAR_OPTEE_PAGEABLE_LOAD_BASE,
+	    .image_info.image_max_size = POPLAR_OPTEE_PAGEABLE_LOAD_SIZE,
+#endif
+	    .next_handoff_image_id = INVALID_IMAGE_ID,
+	},
 # endif /* BL32_BASE */
 
 	/* Fill BL33 related information */
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
index a338396fa22ab01f31830ebab2bc39158c5279c9..177630b0359fce4be4299934b348d9c0a39dfb41 100644
--- a/plat/hisilicon/poplar/bl2_plat_setup.c
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <generic_delay_timer.h>
 #include <mmio.h>
+#include <optee_utils.h>
 #include <partition/partition.h>
 #include <platform.h>
 #include <string.h>
@@ -142,12 +143,37 @@ int poplar_bl2_handle_post_image_load(unsigned int image_id)
 {
 	int err = 0;
 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+#ifdef SPD_opteed
+	bl_mem_params_node_t *pager_mem_params = NULL;
+	bl_mem_params_node_t *paged_mem_params = NULL;
+#endif
 
 	assert(bl_mem_params);
 
 	switch (image_id) {
 #ifdef AARCH64
 	case BL32_IMAGE_ID:
+#ifdef SPD_opteed
+		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+		assert(pager_mem_params);
+
+		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+		assert(paged_mem_params);
+
+		err = parse_optee_header(&bl_mem_params->ep_info,
+				&pager_mem_params->image_info,
+				&paged_mem_params->image_info);
+		if (err != 0) {
+			WARN("OPTEE header parse error.\n");
+		}
+
+		/*
+		 * OP-TEE expect to receive DTB address in x2.
+		 * This will be copied into x2 by dispatcher.
+		 * Set this (arg3) if necessary
+		 */
+		/* bl_mem_params->ep_info.args.arg3 = PLAT_HIKEY_DT_BASE; */
+#endif
 		bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl32_entry();
 		break;
 #endif
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index f626809311755b0d1fa2458a7e010f512af2a97f..805c152adabe0be1bc2824aa1d34e4c13dc626af 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -88,6 +88,14 @@
 #define BL32_DRAM_BASE			0x03000000
 #define BL32_DRAM_LIMIT			0x04000000
 
+#if LOAD_IMAGE_V2
+#ifdef SPD_opteed
+/* Load pageable part of OP-TEE at end of allocated DRAM space for BL32 */
+#define POPLAR_OPTEE_PAGEABLE_LOAD_SIZE	0x400000 /* 4MB */
+#define POPLAR_OPTEE_PAGEABLE_LOAD_BASE	(BL32_DRAM_LIMIT - POPLAR_OPTEE_PAGEABLE_LOAD_SIZE) /* 0x03C0_0000 */
+#endif
+#endif
+
 #if (POPLAR_TSP_RAM_LOCATION_ID == POPLAR_DRAM_ID)
 #define TSP_SEC_MEM_BASE		BL32_DRAM_BASE
 #define TSP_SEC_MEM_SIZE		(BL32_DRAM_LIMIT - BL32_DRAM_BASE)
diff --git a/plat/hisilicon/poplar/plat_storage.c b/plat/hisilicon/poplar/plat_storage.c
index 468e229264a39fd133dd571a8ed117c5b61ce0b3..db52c67626f22c46d2d8e34dc2c688db784186c6 100644
--- a/plat/hisilicon/poplar/plat_storage.c
+++ b/plat/hisilicon/poplar/plat_storage.c
@@ -70,6 +70,14 @@ static const io_uuid_spec_t bl32_uuid_spec = {
 	.uuid = UUID_SECURE_PAYLOAD_BL32,
 };
 
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
 static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
@@ -109,6 +117,16 @@ static const struct plat_io_policy policies[] = {
 		(uintptr_t)&bl32_uuid_spec,
 		open_fip
 	},
+	[BL32_EXTRA1_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra1_uuid_spec,
+		open_fip
+	},
+	[BL32_EXTRA2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra2_uuid_spec,
+		open_fip
+	},
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
index 6616ac7a12689c50e591d7882d3c8d66a24eaea3..58f21ed1d91b87dd837a00984b33e323964f7a20 100644
--- a/plat/hisilicon/poplar/platform.mk
+++ b/plat/hisilicon/poplar/platform.mk
@@ -31,6 +31,15 @@ $(eval $(call add_define,POPLAR_DRAM_SIZE_ID))
 POPLAR_RECOVERY		:= 0
 $(eval $(call add_define,POPLAR_RECOVERY))
 
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call FIP_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call FIP_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+
 NEED_BL33			:= yes
 
 COLD_BOOT_SINGLE_CPU		:= 1
@@ -100,6 +109,11 @@ BL2_SOURCES	+=							\
 		plat/hisilicon/poplar/bl2_plat_mem_params_desc.c	\
 		plat/hisilicon/poplar/poplar_image_load.c		\
 		common/desc_image_load.c
+
+ifeq (${SPD},opteed)
+BL2_SOURCES	+=							\
+		lib/optee/optee_utils.c
+endif
 endif
 
 BL31_SOURCES	+=							\