diff --git a/Makefile b/Makefile
index 49d7cc4b365f4c76b378a7a4b4b5856022ed3ef5..376db8d2f5d8bc77705adaf829a61dcbb951e920 100644
--- a/Makefile
+++ b/Makefile
@@ -115,7 +115,8 @@ ENABLE_PSCI_STAT	:= 0
 # Whether code and read-only data should be put on separate memory pages.
 # The platform Makefile is free to override this value.
 SEPARATE_CODE_AND_RODATA	:= 0
-
+# Flag to enable new version of image loading
+LOAD_IMAGE_V2		:= 0
 
 ################################################################################
 # Checkpatch script options
@@ -355,6 +356,13 @@ ifeq (${NEED_BL33},yes)
         endif
 endif
 
+# TRUSTED_BOARD_BOOT is currently not supported when LOAD_IMAGE_V2 is enabled.
+ifeq (${LOAD_IMAGE_V2},1)
+        ifeq (${TRUSTED_BOARD_BOOT},1)
+                $(error "TRUSTED_BOARD_BOOT is currently not supported	\
+                for LOAD_IMAGE_V2=1")
+        endif
+endif
 
 ################################################################################
 # Process platform overrideable behaviour
@@ -445,6 +453,7 @@ $(eval $(call assert_boolean,PL011_GENERIC_UART))
 $(eval $(call assert_boolean,ENABLE_PMF))
 $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
 $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
+$(eval $(call assert_boolean,LOAD_IMAGE_V2))
 
 
 ################################################################################
@@ -475,6 +484,7 @@ $(eval $(call add_define,PL011_GENERIC_UART))
 $(eval $(call add_define,ENABLE_PMF))
 $(eval $(call add_define,ENABLE_PSCI_STAT))
 $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
+$(eval $(call add_define,LOAD_IMAGE_V2))
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
         $(eval $(call add_define,EL3_PAYLOAD_BASE))
diff --git a/common/bl_common.c b/common/bl_common.c
index bae02d4bf39d2c0a2e7ae05a130b725679282baa..193e972c3ecadba956cfb8e6b28a32f78660c277 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -53,10 +53,7 @@ uintptr_t page_align(uintptr_t value, unsigned dir)
 	return value;
 }
 
-static inline unsigned int is_page_aligned (uintptr_t addr) {
-	return (addr & (PAGE_SIZE - 1)) == 0;
-}
-
+#if !LOAD_IMAGE_V2
 /******************************************************************************
  * Determine whether the memory region delimited by 'addr' and 'size' is free,
  * given the extents of free memory.
@@ -179,6 +176,7 @@ static void dump_load_info(uintptr_t image_load_addr,
 	INFO("  free region = [base = %p, size = 0x%zx]\n",
 		(void *) mem_layout->free_base, mem_layout->free_size);
 }
+#endif /* LOAD_IMAGE_V2 */
 
 /* Generic function to return the size of an image */
 size_t image_size(unsigned int image_id)
@@ -223,6 +221,156 @@ size_t image_size(unsigned int image_id)
 	return image_size;
 }
 
+#if LOAD_IMAGE_V2
+
+/*******************************************************************************
+ * Generic function to load an image at a specific address given
+ * an image ID and extents of free memory.
+ *
+ * If the load is successful then the image information is updated.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ ******************************************************************************/
+int load_image(unsigned int image_id, image_info_t *image_data)
+{
+	uintptr_t dev_handle;
+	uintptr_t image_handle;
+	uintptr_t image_spec;
+	uintptr_t image_base;
+	size_t image_size;
+	size_t bytes_read;
+	int io_result;
+
+	assert(image_data != NULL);
+	assert(image_data->h.version >= VERSION_2);
+
+	image_base = image_data->image_base;
+
+	/* Obtain a reference to the image by querying the platform layer */
+	io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
+	if (io_result != 0) {
+		WARN("Failed to obtain reference to image id=%u (%i)\n",
+			image_id, io_result);
+		return io_result;
+	}
+
+	/* Attempt to access the image */
+	io_result = io_open(dev_handle, image_spec, &image_handle);
+	if (io_result != 0) {
+		WARN("Failed to access image id=%u (%i)\n",
+			image_id, io_result);
+		return io_result;
+	}
+
+	INFO("Loading image id=%u at address %p\n", image_id,
+		(void *) image_base);
+
+	/* Find the size of the image */
+	io_result = io_size(image_handle, &image_size);
+	if ((io_result != 0) || (image_size == 0)) {
+		WARN("Failed to determine the size of the image id=%u (%i)\n",
+			image_id, io_result);
+		goto exit;
+	}
+
+	/* Check that the image size to load is within limit */
+	if (image_size > image_data->image_max_size) {
+		WARN("Image id=%u size out of bounds\n", image_id);
+		io_result = -EFBIG;
+		goto exit;
+	}
+
+	image_data->image_size = image_size;
+
+	/* We have enough space so load the image now */
+	/* TODO: Consider whether to try to recover/retry a partially successful read */
+	io_result = io_read(image_handle, image_base, image_size, &bytes_read);
+	if ((io_result != 0) || (bytes_read < image_size)) {
+		WARN("Failed to load image id=%u (%i)\n", image_id, io_result);
+		goto exit;
+	}
+
+#if !TRUSTED_BOARD_BOOT
+	/*
+	 * File has been successfully loaded.
+	 * Flush the image to main memory so that it can be executed later by
+	 * any CPU, regardless of cache and MMU state.
+	 * When TBB is enabled the image is flushed later, after image
+	 * authentication.
+	 */
+	flush_dcache_range(image_base, image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+	INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base,
+	     (void *) (image_base + image_size));
+
+exit:
+	io_close(image_handle);
+	/* Ignore improbable/unrecoverable error in 'close' */
+
+	/* TODO: Consider maintaining open device connection from this bootloader stage */
+	io_dev_close(dev_handle);
+	/* Ignore improbable/unrecoverable error in 'dev_close' */
+
+	return io_result;
+}
+
+/*******************************************************************************
+ * Generic function to load and authenticate an image. The image is actually
+ * loaded by calling the 'load_image()' function. Therefore, it returns the
+ * same error codes if the loading operation failed, or -EAUTH if the
+ * authentication failed. In addition, this function uses recursion to
+ * authenticate the parent images up to the root of trust.
+ ******************************************************************************/
+int load_auth_image(unsigned int image_id, image_info_t *image_data)
+{
+	int rc;
+
+#if TRUSTED_BOARD_BOOT
+	unsigned int parent_id;
+
+	/* Use recursion to authenticate parent images */
+	rc = auth_mod_get_parent_id(image_id, &parent_id);
+	if (rc == 0) {
+		rc = load_auth_image(parent_id, image_data);
+		if (rc != 0) {
+			return rc;
+		}
+	}
+#endif /* TRUSTED_BOARD_BOOT */
+
+	/* Load the image */
+	rc = load_image(image_id, image_data);
+	if (rc != 0) {
+		return rc;
+	}
+
+#if TRUSTED_BOARD_BOOT
+	/* Authenticate it */
+	rc = auth_mod_verify_img(image_id,
+				 (void *)image_data->image_base,
+				 image_data->image_size);
+	if (rc != 0) {
+		memset((void *)image_data->image_base, 0x00,
+		       image_data->image_size);
+		flush_dcache_range(image_data->image_base,
+				   image_data->image_size);
+		return -EAUTH;
+	}
+
+	/*
+	 * File has been successfully loaded and authenticated.
+	 * Flush the image to main memory so that it can be executed later by
+	 * any CPU, regardless of cache and MMU state.
+	 */
+	flush_dcache_range(image_data->image_base, image_data->image_size);
+#endif /* TRUSTED_BOARD_BOOT */
+
+	return 0;
+}
+
+#else /* LOAD_IMAGE_V2 */
+
 /*******************************************************************************
  * Generic function to load an image at a specific address given an image ID and
  * extents of free memory.
@@ -255,7 +403,7 @@ int load_image(meminfo_t *mem_layout,
 
 	assert(mem_layout != NULL);
 	assert(image_data != NULL);
-	assert(image_data->h.version >= VERSION_1);
+	assert(image_data->h.version == VERSION_1);
 
 	/* Obtain a reference to the image by querying the platform layer */
 	io_result = plat_get_image_source(image_id, &dev_handle, &image_spec);
@@ -348,8 +496,10 @@ exit:
 
 /*******************************************************************************
  * Generic function to load and authenticate an image. The image is actually
- * loaded by calling the 'load_image()' function. In addition, this function
- * uses recursion to authenticate the parent images up to the root of trust.
+ * loaded by calling the 'load_image()' function. Therefore, it returns the
+ * same error codes if the loading operation failed, or -EAUTH if the
+ * authentication failed. In addition, this function uses recursion to
+ * authenticate the parent images up to the root of trust.
  ******************************************************************************/
 int load_auth_image(meminfo_t *mem_layout,
 		    unsigned int image_id,
@@ -403,6 +553,8 @@ int load_auth_image(meminfo_t *mem_layout,
 	return 0;
 }
 
+#endif /* LOAD_IMAGE_V2 */
+
 /*******************************************************************************
  * Print the content of an entry_point_info_t structure.
  ******************************************************************************/
diff --git a/common/desc_image_load.c b/common/desc_image_load.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9762b71704edc72882a14dae2abbfb86b9e82d6
--- /dev/null
+++ b/common/desc_image_load.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <desc_image_load.h>
+
+
+extern bl_mem_params_node_t *bl_mem_params_desc_ptr;
+extern unsigned int bl_mem_params_desc_num;
+
+static bl_load_info_t bl_load_info;
+static bl_params_t next_bl_params;
+
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void flush_bl_params_desc(void)
+{
+	flush_dcache_range((unsigned long)bl_mem_params_desc_ptr,
+			sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num);
+}
+
+/*******************************************************************************
+ * This function returns the index for given image_id, within the
+ * image descriptor array provided by bl_image_info_descs_ptr, if the
+ * image is found else it returns -1.
+ ******************************************************************************/
+int get_bl_params_node_index(unsigned int image_id)
+{
+	int index;
+	assert(image_id != INVALID_IMAGE_ID);
+
+	for (index = 0; index < bl_mem_params_desc_num; index++) {
+		if (bl_mem_params_desc_ptr[index].image_id == image_id)
+			return index;
+	}
+
+	return -1;
+}
+
+/*******************************************************************************
+ * This function returns the pointer to `bl_mem_params_node_t` object for
+ * given image_id, within the image descriptor array provided by
+ * bl_mem_params_desc_ptr, if the image is found else it returns NULL.
+ ******************************************************************************/
+bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id)
+{
+	int index;
+	assert(image_id != INVALID_IMAGE_ID);
+
+	index = get_bl_params_node_index(image_id);
+	if (index >= 0)
+		return &bl_mem_params_desc_ptr[index];
+	else
+		return NULL;
+}
+
+/*******************************************************************************
+ * This function creates the list of loadable images, by populating and
+ * linking each `bl_load_info_node_t` type node, using the internal array
+ * of image descriptor provided by bl_mem_params_desc_ptr. It also populates
+ * and returns `bl_load_info_t` type structure that contains head of the list
+ * of loadable images.
+ ******************************************************************************/
+bl_load_info_t *get_bl_load_info_from_mem_params_desc(void)
+{
+	int index = 0;
+
+	/* If there is no image to start with, return NULL */
+	if (!bl_mem_params_desc_num)
+		return NULL;
+
+	/* Assign initial data structures */
+	bl_load_info_node_t *bl_node_info =
+		&bl_mem_params_desc_ptr[index].load_node_mem;
+	bl_load_info.head = bl_node_info;
+	SET_PARAM_HEAD(&bl_load_info, PARAM_BL_LOAD_INFO, VERSION_2, 0);
+
+	/* Go through the image descriptor array and create the list */
+	for (; index < bl_mem_params_desc_num; index++) {
+
+		/* Populate the image information */
+		bl_node_info->image_id = bl_mem_params_desc_ptr[index].image_id;
+		bl_node_info->image_info = &bl_mem_params_desc_ptr[index].image_info;
+
+		/* Link next image if present */
+		if ((index + 1) < bl_mem_params_desc_num) {
+			/* Get the memory and link the next node */
+			bl_node_info->next_load_info =
+				&bl_mem_params_desc_ptr[index + 1].load_node_mem;
+			bl_node_info = bl_node_info->next_load_info;
+		}
+	}
+
+	return &bl_load_info;
+}
+
+/*******************************************************************************
+ * This function creates the list of executable images, by populating and
+ * linking each `bl_params_node_t` type node, using the internal array of
+ * image descriptor provided by bl_mem_params_desc_ptr. It also populates
+ * and returns `bl_params_t` type structure that contains head of the list
+ * of executable images.
+ ******************************************************************************/
+bl_params_t *get_next_bl_params_from_mem_params_desc(void)
+{
+	int count;
+	unsigned int img_id = 0;
+	int link_index = 0;
+	bl_params_node_t *bl_current_exec_node = NULL;
+	bl_params_node_t *bl_last_exec_node = NULL;
+	bl_mem_params_node_t *desc_ptr;
+
+	/* If there is no image to start with, return NULL */
+	if (!bl_mem_params_desc_num)
+		return NULL;
+
+	/* Get the list HEAD */
+	for (count = 0; count < bl_mem_params_desc_num; count++) {
+
+		desc_ptr = &bl_mem_params_desc_ptr[count];
+
+		if ((EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE) &&
+			(EP_GET_FIRST_EXE(desc_ptr->ep_info.h.attr) == EP_FIRST_EXE)) {
+			next_bl_params.head = &desc_ptr->params_node_mem;
+			link_index = count;
+			break;
+		}
+	}
+
+	/* Make sure we have a HEAD node */
+	assert(next_bl_params.head != NULL);
+
+	/* Populate the HEAD information */
+	SET_PARAM_HEAD(&next_bl_params, PARAM_BL_PARAMS, VERSION_2, 0);
+
+	/*
+	 * Go through the image descriptor array and create the list.
+	 * This bounded loop is to make sure that we are not looping forever.
+	 */
+	for (count = 0 ; count < bl_mem_params_desc_num; count++) {
+
+		desc_ptr = &bl_mem_params_desc_ptr[link_index];
+
+		/* Make sure the image is executable */
+		assert(EP_GET_EXE(desc_ptr->ep_info.h.attr) == EXECUTABLE);
+
+		/* Get the memory for current node */
+		bl_current_exec_node = &desc_ptr->params_node_mem;
+
+		/* Populate the image information */
+		bl_current_exec_node->image_id = desc_ptr->image_id;
+		bl_current_exec_node->image_info = &desc_ptr->image_info;
+		bl_current_exec_node->ep_info = &desc_ptr->ep_info;
+
+		if (bl_last_exec_node) {
+			/* Assert if loop detected */
+			assert(bl_last_exec_node->next_params_info == NULL);
+
+			/* Link the previous node to the current one */
+			bl_last_exec_node->next_params_info = bl_current_exec_node;
+		}
+
+		/* Update the last node */
+		bl_last_exec_node = bl_current_exec_node;
+
+		/* If no next hand-off image then break out */
+		img_id = desc_ptr->next_handoff_image_id;
+		if (img_id == INVALID_IMAGE_ID)
+			break;
+
+		/* Get the index for the next hand-off image */
+		link_index = get_bl_params_node_index(img_id);
+		assert((link_index > 0) &&
+			(link_index < bl_mem_params_desc_num));
+	}
+
+	/* Invalid image is expected to terminate the loop */
+	assert(img_id == INVALID_IMAGE_ID);
+
+	/* Populate arg0 for the next BL image */
+	next_bl_params.head->ep_info->args.arg0 = (unsigned long)&next_bl_params;
+
+	/* Flush the parameters to be passed to the next BL image */
+	flush_dcache_range((unsigned long)&next_bl_params,
+			sizeof(next_bl_params));
+
+	return &next_bl_params;
+}
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 195c9374decd4c2846788fc51cd83f4ee2e66e77..f42ff6498e44b03e343c5b344edacf7b99feb864 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -721,7 +721,6 @@ Firmware represents the power domain topology and how this relates to the
 linear CPU index, please refer [Power Domain Topology Design].
 
 
-
 2.4 Common optional modifications
 ---------------------------------
 
@@ -841,10 +840,37 @@ and must be implemented in assembly because it may be called before the C
 environment is initialized.
 
 Note: The address from where it was called is stored in x30 (Link Register).
-
 The default implementation simply spins.
 
 
+### Function : plat_get_bl_image_load_info()
+
+    Argument : void
+    Return   : bl_load_info_t *
+
+This function returns pointer to the list of images that the platform has
+populated to load. This function is currently invoked in BL2 to load the
+BL3xx images, when LOAD_IMAGE_V2 is enabled.
+
+### Function : plat_get_next_bl_params()
+
+    Argument : void
+    Return   : bl_params_t *
+
+This function returns a pointer to the shared memory that the platform has
+kept aside to pass trusted firmware related information that next BL image
+needs. This function is currently invoked in BL2 to pass this information to
+the next BL image, when LOAD_IMAGE_V2 is enabled.
+
+### Function : plat_flush_next_bl_params()
+
+    Argument : void
+    Return   : void
+
+This function flushes to main memory all the image params that are passed to
+next image. This function is currently invoked in BL2 to flush this information
+to the next BL image, when LOAD_IMAGE_V2 is enabled.
+
 3.  Modifications specific to a Boot Loader stage
 -------------------------------------------------
 
@@ -1175,6 +1201,20 @@ populated with the extents of secure RAM available for BL2 to use. See
 `bl2_early_platform_setup()` above.
 
 
+Following function is required only when LOAD_IMAGE_V2 is enabled.
+
+### Function : bl2_plat_handle_post_image_load() [mandatory]
+
+    Argument : unsigned int
+    Return   : int
+
+This function can be used by the platforms to update/use image information
+for given `image_id`. This function is currently invoked in BL2 to handle
+BL image specific information based on the `image_id` passed, when
+LOAD_IMAGE_V2 is enabled.
+
+Following functions are required only when LOAD_IMAGE_V2 is disabled.
+
 ### Function : bl2_plat_get_scp_bl2_meminfo() [mandatory]
 
     Argument : meminfo *
diff --git a/docs/user-guide.md b/docs/user-guide.md
index d545262c393b1767d547716d5539b01eb3ed0d7b..d7d743accb751fb1fa9aaadbdd7fc381db7f770d 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -430,6 +430,12 @@ performed.
     pages" section in [Firmware Design]. This flag is disabled by default and
     affects all BL images.
 
+*   `LOAD_IMAGE_V2`: Boolean option to enable support for new version (v2) of
+    image loading, which provides more flexibility and scalability around what
+    images are loaded and executed during boot. Default is 0.
+    Note: `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2`
+    is enabled.
+
 #### ARM development platform specific build options
 
 *   `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options:
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 942843cf12734dd46a82372ad26dfff913b89d38..9fa2a810e46debeca368feac129d713f98ac45ed 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -93,11 +93,22 @@
 #define EP_GET_EXE(x) (x & EP_EXE_MASK)
 #define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee))
 
+#define EP_FIRST_EXE_MASK	0x10
+#define EP_FIRST_EXE		0x10
+#define EP_GET_FIRST_EXE(x) ((x) & EP_FIRST_EXE_MASK)
+#define EP_SET_FIRST_EXE(x, ee) ((x) = ((x) & ~EP_FIRST_EXE_MASK) | (ee))
+
 #define PARAM_EP		0x01
 #define PARAM_IMAGE_BINARY	0x02
 #define PARAM_BL31		0x03
+#define PARAM_BL_LOAD_INFO	0x04
+#define PARAM_BL_PARAMS		0x05
+
+#define IMAGE_ATTRIB_SKIP_LOADING	0x02
+#define IMAGE_ATTRIB_PLAT_SETUP		0x04
 
 #define VERSION_1	0x01
+#define VERSION_2	0x02
 
 #define INVALID_IMAGE_ID		(0xFFFFFFFF)
 
@@ -181,8 +192,10 @@ extern uintptr_t __COHERENT_RAM_END__;
 typedef struct meminfo {
 	uintptr_t total_base;
 	size_t total_size;
+#if !LOAD_IMAGE_V2
 	uintptr_t free_base;
 	size_t free_size;
+#endif
 } meminfo_t;
 
 typedef struct aapcs64_params {
@@ -245,6 +258,9 @@ typedef struct image_info {
 	param_header_t h;
 	uintptr_t image_base;   /* physical address of base of image */
 	uint32_t image_size;    /* bytes read from image file */
+#if LOAD_IMAGE_V2
+	uint32_t image_max_size;
+#endif
 } image_info_t;
 
 /*****************************************************************************
@@ -263,6 +279,39 @@ typedef struct image_desc {
 	entry_point_info_t ep_info;
 } image_desc_t;
 
+#if LOAD_IMAGE_V2
+/* BL image node in the BL image loading sequence */
+typedef struct bl_load_info_node {
+	unsigned int image_id;
+	image_info_t *image_info;
+	struct bl_load_info_node *next_load_info;
+} bl_load_info_node_t;
+
+/* BL image head node in the BL image loading sequence */
+typedef struct bl_load_info {
+	param_header_t h;
+	bl_load_info_node_t *head;
+} bl_load_info_t;
+
+/* BL image node in the BL image execution sequence */
+typedef struct bl_params_node {
+	unsigned int image_id;
+	image_info_t *image_info;
+	entry_point_info_t *ep_info;
+	struct bl_params_node *next_params_info;
+} bl_params_node_t;
+
+/*
+ * BL image head node in the BL image execution sequence
+ * It is also used to pass information to next BL image.
+ */
+typedef struct bl_params {
+	param_header_t h;
+	bl_params_node_t *head;
+} bl_params_t;
+
+#else /* LOAD_IMAGE_V2 */
+
 /*******************************************************************************
  * This structure represents the superset of information that can be passed to
  * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
@@ -286,6 +335,7 @@ typedef struct bl31_params {
 	image_info_t *bl33_image_info;
 } bl31_params_t;
 
+#endif /* LOAD_IMAGE_V2 */
 
 /*
  * Compile time assertions related to the 'entry_point_info' structure to
@@ -308,24 +358,34 @@ CASSERT(sizeof(uintptr_t) ==
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
-uintptr_t page_align(uintptr_t, unsigned);
 size_t image_size(unsigned int image_id);
+
+#if LOAD_IMAGE_V2
+
+int load_image(unsigned int image_id, image_info_t *image_data);
+int load_auth_image(unsigned int image_id, image_info_t *image_data);
+
+#else
+
+uintptr_t page_align(uintptr_t, unsigned);
 int load_image(meminfo_t *mem_layout,
 	       unsigned int image_id,
 	       uintptr_t image_base,
 	       image_info_t *image_data,
 	       entry_point_info_t *entry_point_info);
 int load_auth_image(meminfo_t *mem_layout,
-		    unsigned int image_name,
+		    unsigned int image_id,
 		    uintptr_t image_base,
 		    image_info_t *image_data,
 		    entry_point_info_t *entry_point_info);
-extern const char build_message[];
-extern const char version_string[];
-
 void reserve_mem(uintptr_t *free_base, size_t *free_size,
 		uintptr_t addr, size_t size);
 
+#endif /* LOAD_IMAGE_V2 */
+
+extern const char build_message[];
+extern const char version_string[];
+
 void print_entry_point_info(const entry_point_info_t *ep_info);
 
 #endif /*__ASSEMBLY__*/
diff --git a/include/common/desc_image_load.h b/include/common/desc_image_load.h
new file mode 100644
index 0000000000000000000000000000000000000000..78342627c6451093bad8187e6e92db5049118a9a
--- /dev/null
+++ b/include/common/desc_image_load.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __DESC_IMAGE_LOAD_H__
+#define __DESC_IMAGE_LOAD_H__
+
+#include <bl_common.h>
+
+#if LOAD_IMAGE_V2
+/* Following structure is used to store BL ep/image info. */
+typedef struct bl_mem_params_node {
+	unsigned int image_id;
+	image_info_t image_info;
+	entry_point_info_t ep_info;
+	unsigned int next_handoff_image_id;
+	bl_load_info_node_t load_node_mem;
+	bl_params_node_t params_node_mem;
+} bl_mem_params_node_t;
+
+/*
+ * Macro to register list of BL image descriptors,
+ * defined as an array of bl_mem_params_node_t.
+ */
+#define REGISTER_BL_IMAGE_DESCS(_img_desc)				\
+	bl_mem_params_node_t *bl_mem_params_desc_ptr = &_img_desc[0];	\
+	unsigned int bl_mem_params_desc_num = ARRAY_SIZE(_img_desc);
+
+/* BL image loading utility functions */
+void flush_bl_params_desc(void);
+int get_bl_params_node_index(unsigned int image_id);
+bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id);
+bl_load_info_t *get_bl_load_info_from_mem_params_desc(void);
+bl_params_t *get_next_bl_params_from_mem_params_desc(void);
+
+
+#endif /* LOAD_IMAGE_V2 */
+#endif /* __DESC_IMAGE_LOAD_H__ */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index 1d2a3739ecb824a0d29b5f34c2320b35d19d4b82..852ccbcd018e2fea107cb7ad7a9041ef51863367 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -44,6 +44,8 @@ struct image_info;
 struct entry_point_info;
 struct bl31_params;
 struct image_desc;
+struct bl_load_info;
+struct bl_params;
 
 /*******************************************************************************
  * plat_get_rotpk_info() flags
@@ -138,6 +140,15 @@ void bl2_plat_arch_setup(void);
 void bl2_platform_setup(void);
 struct meminfo *bl2_plat_sec_mem_layout(void);
 
+#if LOAD_IMAGE_V2
+/*
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ */
+int bl2_plat_handle_post_image_load(unsigned int image_id);
+
+#else /* LOAD_IMAGE_V2 */
+
 /*
  * This function returns a pointer to the shared memory that the platform has
  * kept aside to pass trusted firmware related information that BL31
@@ -194,6 +205,8 @@ void bl2_plat_set_bl32_ep_info(struct image_info *image,
 /* Gets the memory layout for BL32 */
 void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
 
+#endif /* LOAD_IMAGE_V2 */
+
 /*******************************************************************************
  * Optional BL2 functions (may be overridden)
  ******************************************************************************/
@@ -218,8 +231,13 @@ int bl2u_plat_handle_scp_bl2u(void);
 /*******************************************************************************
  * Mandatory BL31 functions
  ******************************************************************************/
+#if LOAD_IMAGE_V2
+void bl31_early_platform_setup(void *from_bl2,
+				void *plat_params_from_bl2);
+#else
 void bl31_early_platform_setup(struct bl31_params *from_bl2,
 				void *plat_params_from_bl2);
+#endif
 void bl31_plat_arch_setup(void);
 void bl31_platform_setup(void);
 void bl31_plat_runtime_setup(void);
@@ -257,6 +275,31 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
 int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr);
 int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
 
+#if LOAD_IMAGE_V2
+/*******************************************************************************
+ * Mandatory BL image load functions(may be overridden).
+ ******************************************************************************/
+/*
+ * This function returns pointer to the list of images that the
+ * platform has populated to load.
+ */
+struct bl_load_info *plat_get_bl_image_load_info(void);
+
+/*
+ * This function returns a pointer to the shared memory that the
+ * platform has kept aside to pass trusted firmware related
+ * information that next BL image could need.
+ */
+struct bl_params *plat_get_next_bl_params(void);
+
+/*
+ * This function flushes to main memory all the params that are
+ * passed to next image.
+ */
+void plat_flush_next_bl_params(void);
+
+#endif /* LOAD_IMAGE_V2 */
+
 #if ENABLE_PLAT_COMPAT
 /*
  * The below declarations are to enable compatibility for the platform ports