diff --git a/cmd/Kconfig b/cmd/Kconfig
index d532c9fc41c05f8b43ee2553c2d441d43ebed211..c4e831eb4e0e7de82519db50774bce4b3d32f84f 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -697,6 +697,13 @@ config CMD_FPGA_LOADP
 	  Supports loading an FPGA device from a bitstream buffer containing
 	  a partial bitstream.
 
+config CMD_FPGA_LOAD_SECURE
+	bool "fpga loads - loads secure bitstreams (Xilinx only)"
+	depends on CMD_FPGA
+	help
+	  Enables the fpga loads command which is used to load secure
+	  (authenticated or encrypted or both) bitstreams on to FPGA.
+
 config CMD_FPGAD
 	bool "fpgad - dump FPGA registers"
 	help
diff --git a/cmd/fpga.c b/cmd/fpga.c
index 3f09d424135f87ca50f34b41b4b8dffa9b06dbb5..74ae80c807e20a3698da0a3bf8d040611cd59d31 100644
--- a/cmd/fpga.c
+++ b/cmd/fpga.c
@@ -27,6 +27,7 @@ enum {
 	FPGA_LOADP,
 	FPGA_LOADBP,
 	FPGA_LOADFS,
+	FPGA_LOADS,
 };
 
 /* ------------------------------------------------------------------------- */
@@ -54,6 +55,11 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 	fpga_fs_info fpga_fsinfo;
 	fpga_fsinfo.fstype = FS_TYPE_ANY;
 #endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	struct fpga_secure_info fpga_sec_info;
+
+	memset(&fpga_sec_info, 0, sizeof(fpga_sec_info));
+#endif
 
 	if (devstr)
 		dev = (int) simple_strtoul(devstr, NULL, 16);
@@ -79,6 +85,19 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 		fpga_fsinfo.filename = argv[8];
 		argc = 5;
 		break;
+#endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		if (argc < 7)
+			return CMD_RET_USAGE;
+		if (argc == 8)
+			fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
+						     simple_strtoull(argv[7],
+								     NULL, 16);
+		fpga_sec_info.encflag = (u8)simple_strtoul(argv[6], NULL, 16);
+		fpga_sec_info.authflag = (u8)simple_strtoul(argv[5], NULL, 16);
+		argc = 5;
+		break;
 #endif
 	default:
 		break;
@@ -150,6 +169,22 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 		if (!fpga_fsinfo.interface || !fpga_fsinfo.dev_part ||
 		    !fpga_fsinfo.filename)
 			wrong_parms = 1;
+		break;
+#endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		if (fpga_sec_info.authflag >= FPGA_NO_ENC_OR_NO_AUTH &&
+		    fpga_sec_info.encflag >= FPGA_NO_ENC_OR_NO_AUTH) {
+			puts("ERR: use <fpga load> for NonSecure bitstream\n");
+			wrong_parms = 1;
+		}
+
+		if (fpga_sec_info.encflag == FPGA_ENC_USR_KEY &&
+		    !fpga_sec_info.userkey_addr) {
+			wrong_parms = 1;
+			puts("ERR:User key not provided\n");
+		}
+		break;
 #endif
 	case FPGA_LOAD:
 	case FPGA_LOADP:
@@ -206,6 +241,12 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 		break;
 #endif
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	case FPGA_LOADS:
+		rc = fpga_loads(dev, fpga_data, data_size, &fpga_sec_info);
+		break;
+#endif
+
 #if defined(CONFIG_CMD_FPGA_LOADMK)
 	case FPGA_LOADMK:
 		switch (genimg_get_format(fpga_data)) {
@@ -339,6 +380,10 @@ static int fpga_get_op(char *opstr)
 #endif
 	else if (!strcmp("dump", opstr))
 		op = FPGA_DUMP;
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	else if (!strcmp("loads", opstr))
+		op = FPGA_LOADS;
+#endif
 
 	if (op == FPGA_NONE)
 		printf("Unknown fpga operation \"%s\"\n", opstr);
@@ -346,7 +391,7 @@ static int fpga_get_op(char *opstr)
 	return op;
 }
 
-#if defined(CONFIG_CMD_FPGA_LOADFS)
+#if defined(CONFIG_CMD_FPGA_LOADFS) || defined(CONFIG_CMD_FPGA_LOAD_SECURE)
 U_BOOT_CMD(fpga, 9, 1, do_fpga,
 #else
 U_BOOT_CMD(fpga, 6, 1, do_fpga,
@@ -381,4 +426,19 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga,
 	   "\tsubimage unit name in the form of addr:<subimg_uname>"
 #endif
 #endif
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+	   "Load encrypted bitstream (Xilinx only)\n"
+	   "  loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
+	   "        [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
+	   "Loads the secure bistreams(authenticated/encrypted/both\n"
+	   "authenticated and encrypted) of [size] from [address].\n"
+	   "The auth-OCM/DDR flag specifies to perform authentication\n"
+	   "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
+	   "The enc flag specifies which key to be used for decryption\n"
+	   "0-device key, 1-user key, 2-no encryption.\n"
+	   "The optional Userkey address specifies from which address key\n"
+	   "has to be used for decryption if user key is selected.\n"
+	   "NOTE: the sceure bitstream has to be created using xilinx\n"
+	   "bootgen tool only.\n"
+#endif
 );
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index 55bdf9e7cf290e4cd405cdc2ece0c3c59d291177..7e8bd7eae881d23c641eb1869b099db19c82f652 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -217,6 +217,35 @@ int fpga_fsload(int devnum, const void *buf, size_t size,
 }
 #endif
 
+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+int fpga_loads(int devnum, const void *buf, size_t size,
+	       struct fpga_secure_info *fpga_sec_info)
+{
+	int ret_val = FPGA_FAIL;
+
+	const fpga_desc *desc = fpga_validate(devnum, buf, size,
+					      (char *)__func__);
+
+	if (desc) {
+		switch (desc->devtype) {
+		case fpga_xilinx:
+#if defined(CONFIG_FPGA_XILINX)
+			ret_val = xilinx_loads(desc->devdesc, buf, size,
+					       fpga_sec_info);
+#else
+			fpga_no_sup((char *)__func__, "Xilinx devices");
+#endif
+			break;
+		default:
+			printf("%s: Invalid or unsupported device type %d\n",
+			       __func__, desc->devtype);
+		}
+	}
+
+	return ret_val;
+}
+#endif
+
 /*
  * Generic multiplexing code
  */
diff --git a/include/fpga.h b/include/fpga.h
index f4440933531f41a5ac9a339119200a71bc968f20..195f0bdd57a98b1c3404b7d33b31bc53f986969a 100644
--- a/include/fpga.h
+++ b/include/fpga.h
@@ -20,6 +20,9 @@
 /* device numbers must be non-negative */
 #define FPGA_INVALID_DEVICE	-1
 
+#define FPGA_ENC_USR_KEY	1
+#define FPGA_NO_ENC_OR_NO_AUTH	2
+
 /* root data type defintions */
 typedef enum {			/* typedef fpga_type */
 	fpga_min_type,		/* range check value */
@@ -42,6 +45,12 @@ typedef struct {                /* typedef fpga_desc */
 	int fstype;
 } fpga_fs_info;
 
+struct fpga_secure_info {
+	u8 *userkey_addr;
+	u8 authflag;
+	u8 encflag;
+};
+
 typedef enum {
 	BIT_FULL = 0,
 	BIT_PARTIAL,
@@ -58,6 +67,8 @@ int fpga_load(int devnum, const void *buf, size_t bsize,
 	      bitstream_type bstype);
 int fpga_fsload(int devnum, const void *buf, size_t size,
 		fpga_fs_info *fpga_fsinfo);
+int fpga_loads(int devnum, const void *buf, size_t size,
+	       struct fpga_secure_info *fpga_sec_info);
 int fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
 		       bitstream_type bstype);
 int fpga_dump(int devnum, const void *buf, size_t bsize);