diff --git a/br-ext/Config.in b/br-ext/Config.in
new file mode 100644
index 0000000000000000000000000000000000000000..52f2a6211d7e62256ad92d5a0485b58f8bdcd241
--- /dev/null
+++ b/br-ext/Config.in
@@ -0,0 +1,4 @@
+source "$BR2_EXTERNAL_OPTEE_PATH/package/optee_client/Config.in"
+source "$BR2_EXTERNAL_OPTEE_PATH/package/optee_test/Config.in"
+source "$BR2_EXTERNAL_OPTEE_PATH/package/optee_examples/Config.in"
+source "$BR2_EXTERNAL_OPTEE_PATH/package/optee_benchmark/Config.in"
diff --git a/br-ext/configs/optee_aarch32 b/br-ext/configs/optee_aarch32
new file mode 100644
index 0000000000000000000000000000000000000000..a7f8886a13a66728b745676756b0fb42f54ffa4d
--- /dev/null
+++ b/br-ext/configs/optee_aarch32
@@ -0,0 +1,5 @@
+# Architecture
+BR2_arm=y
+BR2_cortex_a15=y
+BR2_ARM_FPU_VFPV3D16=y
+BR2_ARM_INSTRUCTIONS_THUMB2=y
diff --git a/br-ext/configs/optee_aarch64 b/br-ext/configs/optee_aarch64
new file mode 100644
index 0000000000000000000000000000000000000000..d740c58fcc5934151e4ae59ed8684cf4d97d1c0e
--- /dev/null
+++ b/br-ext/configs/optee_aarch64
@@ -0,0 +1,2 @@
+# Architecture
+BR2_aarch64=y
diff --git a/br-ext/configs/optee_examples b/br-ext/configs/optee_examples
new file mode 100644
index 0000000000000000000000000000000000000000..5d10dd8f0ee59361a963deb3a6e623638e33cd0c
--- /dev/null
+++ b/br-ext/configs/optee_examples
@@ -0,0 +1 @@
+BR2_PACKAGE_OPTEE_EXAMPLES=y
diff --git a/br-ext/configs/optee_generic b/br-ext/configs/optee_generic
new file mode 100644
index 0000000000000000000000000000000000000000..d56b5c9005160527f58ecee76d6f660b200caebc
--- /dev/null
+++ b/br-ext/configs/optee_generic
@@ -0,0 +1,7 @@
+BR2_CCACHE=y
+BR2_TARGET_GENERIC_ISSUE="Welcome to Buildroot, type root to login"
+
+BR2_TARGET_ROOTFS_CPIO=y
+BR2_TARGET_ROOTFS_CPIO_GZIP=y
+BR2_PACKAGE_HOST_E2FSPROGS=y
+BR2_PACKAGE_OPTEE_CLIENT=y
diff --git a/br-ext/configs/optee_test b/br-ext/configs/optee_test
new file mode 100644
index 0000000000000000000000000000000000000000..cb14791aa6523712874cdb43a7afb546be27421e
--- /dev/null
+++ b/br-ext/configs/optee_test
@@ -0,0 +1 @@
+BR2_PACKAGE_OPTEE_TEST=y
diff --git a/br-ext/configs/toolchain-aarch32 b/br-ext/configs/toolchain-aarch32
new file mode 100644
index 0000000000000000000000000000000000000000..95fbfcf3df2c5c5325b94d34f35edd444abb503c
--- /dev/null
+++ b/br-ext/configs/toolchain-aarch32
@@ -0,0 +1,9 @@
+BR2_TOOLCHAIN_EXTERNAL=y
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
+BR2_TOOLCHAIN_EXTERNAL_PATH="%TOP_DIR%/toolchains/aarch32"
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arm-linux-gnueabihf"
+BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
+BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_6=y
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
+BR2_TOOLCHAIN_EXTERNAL_CXX=y
+
diff --git a/br-ext/configs/toolchain-aarch64 b/br-ext/configs/toolchain-aarch64
new file mode 100644
index 0000000000000000000000000000000000000000..24906be3e4ba0c908830d3b40bb1b144c1cb6823
--- /dev/null
+++ b/br-ext/configs/toolchain-aarch64
@@ -0,0 +1,9 @@
+BR2_TOOLCHAIN_EXTERNAL=y
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
+BR2_TOOLCHAIN_EXTERNAL_PATH="%TOP_DIR%/toolchains/aarch64"
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="aarch64-linux-gnu"
+BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
+BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_6=y
+BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC=y
+BR2_TOOLCHAIN_EXTERNAL_CXX=y
+
diff --git a/br-ext/external.desc b/br-ext/external.desc
new file mode 100644
index 0000000000000000000000000000000000000000..02582f512cc7efbf800d7db983d0b3f61a9b1a62
--- /dev/null
+++ b/br-ext/external.desc
@@ -0,0 +1,2 @@
+name: OPTEE
+desc: OP-TEE br2-external tree
diff --git a/br-ext/external.mk b/br-ext/external.mk
new file mode 100644
index 0000000000000000000000000000000000000000..fcf49b2b1fff3b8c6574886e8942ea9071ca6887
--- /dev/null
+++ b/br-ext/external.mk
@@ -0,0 +1 @@
+include $(sort $(wildcard $(BR2_EXTERNAL_OPTEE_PATH)/package/*/*.mk))
diff --git a/br-ext/package/optee_benchmark/Config.in b/br-ext/package/optee_benchmark/Config.in
new file mode 100644
index 0000000000000000000000000000000000000000..5928d5aeec49c4d4790eec7908ed72e135d358a6
--- /dev/null
+++ b/br-ext/package/optee_benchmark/Config.in
@@ -0,0 +1,13 @@
+config BR2_PACKAGE_OPTEE_BENCHMARK
+	bool "optee_benchmark"
+	select BR2_PACKAGE_LIBYAML
+	help
+	  http://github.org/OP-TEE/optee_benchmark
+
+if BR2_PACKAGE_OPTEE_BENCHMARK
+config BR2_PACKAGE_OPTEE_BENCHMARK_SITE
+	string "OP-TEE benchmark path"
+	default ""
+	help
+	  The path to the source directory of OP-TEE benchmark
+endif
diff --git a/br-ext/package/optee_benchmark/optee_benchmark.mk b/br-ext/package/optee_benchmark/optee_benchmark.mk
new file mode 100644
index 0000000000000000000000000000000000000000..676348998e546f8eb0a9d0a2b5d87286284a2619
--- /dev/null
+++ b/br-ext/package/optee_benchmark/optee_benchmark.mk
@@ -0,0 +1,8 @@
+OPTEE_BENCHMARK_VERSION = 1.0
+OPTEE_BENCHMARK_SOURCE = local
+OPTEE_BENCHMARK_SITE = $(BR2_PACKAGE_OPTEE_BENCHMARK_SITE)
+OPTEE_BENCHMARK_SITE_METHOD = local
+OPTEE_BENCHMARK_INSTALL_STAGING = YES
+OPTEE_BENCHMARK_DEPENDENCIES = optee_client libyaml
+
+$(eval $(cmake-package))
diff --git a/br-ext/package/optee_client/Config.in b/br-ext/package/optee_client/Config.in
new file mode 100644
index 0000000000000000000000000000000000000000..435b6eeb09a23908d54665be0585ce89bc2af527
--- /dev/null
+++ b/br-ext/package/optee_client/Config.in
@@ -0,0 +1,12 @@
+config BR2_PACKAGE_OPTEE_CLIENT
+	bool "optee_client"
+	help
+	  http://github.org/OP-TEE/optee_client
+
+if BR2_PACKAGE_OPTEE_CLIENT
+config BR2_PACKAGE_OPTEE_CLIENT_SITE
+	string "OP-TEE client path"
+	default ""
+	help
+	  The path to the source directory of OP-TEE client
+endif
diff --git a/br-ext/package/optee_client/S30optee b/br-ext/package/optee_client/S30optee
new file mode 100755
index 0000000000000000000000000000000000000000..c8932434f32de98f5d3387d21a0925f6da7bec81
--- /dev/null
+++ b/br-ext/package/optee_client/S30optee
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# /etc/init.d/optee
+#
+# Start/stop tee-supplicant (OP-TEE normal world daemon)
+#
+case "$1" in
+    start)
+	if [ -e /usr/sbin/tee-supplicant -a -e /dev/teepriv0 ]; then
+		echo "Starting tee-supplicant..."
+		/usr/sbin/tee-supplicant &
+		exit 0
+	else
+		echo "tee-supplicant or TEE device not found"
+		exit 1
+	fi
+
+        ;;
+    stop)
+	killall tee-supplicant
+	;;
+    status)
+	cat /dev/teepriv0 2>&1 | grep -q "Device or resource busy" || not="not "
+	echo "tee-supplicant is ${not}active"
+	;;
+esac
diff --git a/br-ext/package/optee_client/optee_client.mk b/br-ext/package/optee_client/optee_client.mk
new file mode 100644
index 0000000000000000000000000000000000000000..0b3801032479e902dcb3ac526043003495a22af2
--- /dev/null
+++ b/br-ext/package/optee_client/optee_client.mk
@@ -0,0 +1,16 @@
+OPTEE_CLIENT_VERSION = 1.0
+OPTEE_CLIENT_SOURCE = local
+OPTEE_CLIENT_SITE = $(BR2_PACKAGE_OPTEE_CLIENT_SITE)
+OPTEE_CLIENT_SITE_METHOD = local
+OPTEE_CLIENT_INSTALL_STAGING = YES
+
+define OPTEE_CLIENT_INSTALL_SUPPLICANT_SCRIPT
+	$(INSTALL) -m 0755 -D $(OPTEE_CLIENT_PKGDIR)/S30optee \
+		$(TARGET_DIR)/etc/init.d/S30optee
+endef
+
+define OPTEE_CLIENT_INSTALL_INIT_SYSV
+	$(OPTEE_CLIENT_INSTALL_SUPPLICANT_SCRIPT)
+endef
+
+$(eval $(cmake-package))
diff --git a/br-ext/package/optee_examples/Config.in b/br-ext/package/optee_examples/Config.in
new file mode 100644
index 0000000000000000000000000000000000000000..cd7e3fcd6dfb6502fb0d538ab9e71ec8797cbf09
--- /dev/null
+++ b/br-ext/package/optee_examples/Config.in
@@ -0,0 +1,26 @@
+config BR2_PACKAGE_OPTEE_EXAMPLES
+	bool "optee_examples"
+	help
+	  http://github.org/OP-TEE/optee_examples
+
+if BR2_PACKAGE_OPTEE_EXAMPLES
+
+config BR2_PACKAGE_OPTEE_EXAMPLES_SITE
+	string "OP-TEE examples path"
+	default ""
+	help
+	  The path to the source directory of OP-TEE examples
+
+config BR2_PACKAGE_OPTEE_EXAMPLES_SDK
+	string "OPTEE SDK path"
+	default ""
+	help
+	  some help
+
+config BR2_PACKAGE_OPTEE_EXAMPLES_CROSS_COMPILE
+	string "OPTEE cross compiler"
+	default ""
+	help
+	  some help
+
+endif
diff --git a/br-ext/package/optee_examples/optee_examples.mk b/br-ext/package/optee_examples/optee_examples.mk
new file mode 100644
index 0000000000000000000000000000000000000000..dd6491d937816be16f2d26708c55cec92590eef8
--- /dev/null
+++ b/br-ext/package/optee_examples/optee_examples.mk
@@ -0,0 +1,28 @@
+OPTEE_EXAMPLES_VERSION = 1.0
+OPTEE_EXAMPLES_SOURCE = local
+OPTEE_EXAMPLES_SITE = $(BR2_PACKAGE_OPTEE_EXAMPLES_SITE)
+OPTEE_EXAMPLES_SITE_METHOD = local
+OPTEE_EXAMPLES_INSTALL_STAGING = YES
+OPTEE_EXAMPLES_DEPENDENCIES = optee_client
+OPTEE_EXAMPLES_SDK = $(BR2_PACKAGE_OPTEE_EXAMPLES_SDK)
+OPTEE_EXAMPLES_CONF_OPTS = -DOPTEE_EXAMPLES_SDK=$(OPTEE_EXAMPLES_SDK)
+
+define OPTEE_EXAMPLES_BUILD_TAS
+	@$(foreach f,$(wildcard $(@D)/*/ta/Makefile), \
+		$(MAKE) CROSS_COMPILE="$(shell echo $(BR2_PACKAGE_OPTEE_EXAMPLES_CROSS_COMPILE))" \
+			O=out TA_DEV_KIT_DIR=$(OPTEE_EXAMPLES_SDK) V=1 \
+			$(TARGET_CONFIGURE_OPTS) -C $(dir $f) all &&) true
+endef
+
+define OPTEE_EXAMPLES_INSTALL_TAS
+	@$(foreach f,$(wildcard $(@D)/*/ta/out/*.ta), \
+		mkdir -p $(TARGET_DIR)/lib/optee_armtz && \
+		$(INSTALL) -v -p  --mode=444 \
+			--target-directory=$(TARGET_DIR)/lib/optee_armtz $f \
+			&&) true
+endef
+
+OPTEE_EXAMPLES_POST_BUILD_HOOKS += OPTEE_EXAMPLES_BUILD_TAS
+OPTEE_EXAMPLES_POST_INSTALL_TARGET_HOOKS += OPTEE_EXAMPLES_INSTALL_TAS
+
+$(eval $(cmake-package))
diff --git a/br-ext/package/optee_test/Config.in b/br-ext/package/optee_test/Config.in
new file mode 100644
index 0000000000000000000000000000000000000000..8a435d19fa883b56e8a6c5ad3f64f09cb93fd301
--- /dev/null
+++ b/br-ext/package/optee_test/Config.in
@@ -0,0 +1,27 @@
+config BR2_PACKAGE_OPTEE_TEST
+	bool "optee_test"
+	select BR2_PACKAGE_OPTEE_CLIENT
+	help
+	  http://github.org/OP-TEE/optee_test
+
+if BR2_PACKAGE_OPTEE_TEST
+
+config BR2_PACKAGE_OPTEE_TEST_SITE
+	string "OP-TEE test path"
+	default ""
+	help
+	  The path to the source directory of OP-TEE test
+
+config BR2_PACKAGE_OPTEE_TEST_SDK
+	string "OPTEE SDK path"
+	default ""
+	help
+	  some help
+
+config BR2_PACKAGE_OPTEE_TEST_CROSS_COMPILE
+	string "OPTEE cross compiler"
+	default ""
+	help
+	  some help
+
+endif
diff --git a/br-ext/package/optee_test/optee_test.mk b/br-ext/package/optee_test/optee_test.mk
new file mode 100644
index 0000000000000000000000000000000000000000..797f6ac11d325eb395517f9db9d555d734b6ca5a
--- /dev/null
+++ b/br-ext/package/optee_test/optee_test.mk
@@ -0,0 +1,28 @@
+OPTEE_TEST_VERSION = 1.0
+OPTEE_TEST_SOURCE = local
+OPTEE_TEST_SITE = $(BR2_PACKAGE_OPTEE_TEST_SITE)
+OPTEE_TEST_SITE_METHOD = local
+OPTEE_TEST_INSTALL_STAGING = YES
+OPTEE_TEST_DEPENDENCIES = optee_client
+OPTEE_TEST_SDK = $(BR2_PACKAGE_OPTEE_TEST_SDK)
+OPTEE_TEST_CONF_OPTS = -DOPTEE_TEST_SDK=$(OPTEE_TEST_SDK)
+
+define OPTEE_TEST_BUILD_TAS
+	@$(foreach f,$(wildcard $(@D)/ta/*/Makefile), \
+		$(MAKE) CROSS_COMPILE="$(shell echo $(BR2_PACKAGE_OPTEE_TEST_CROSS_COMPILE))" \
+			O=out TA_DEV_KIT_DIR=$(OPTEE_TEST_SDK) \
+			$(TARGET_CONFIGURE_OPTS) -C $(dir $f) all &&) true
+endef
+
+define OPTEE_TEST_INSTALL_TAS
+	@$(foreach f,$(wildcard $(@D)/ta/*/out/*.ta), \
+		mkdir -p $(TARGET_DIR)/lib/optee_armtz && \
+		$(INSTALL) -v -p  --mode=444 \
+			--target-directory=$(TARGET_DIR)/lib/optee_armtz $f \
+			&&) true
+endef
+
+OPTEE_TEST_POST_BUILD_HOOKS += OPTEE_TEST_BUILD_TAS
+OPTEE_TEST_POST_INSTALL_TARGET_HOOKS += OPTEE_TEST_INSTALL_TAS
+
+$(eval $(cmake-package))
diff --git a/br-ext/scripts/make_def_config.py b/br-ext/scripts/make_def_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..be30ec5dae6a47e3792298ffbbadb3c4bb6e3455
--- /dev/null
+++ b/br-ext/scripts/make_def_config.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: BSD-2-Clause
+# Copyright (c) 2018, Linaro Limited
+
+import argparse
+import shutil
+import os
+import re
+
+def get_args():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--br', required=True,
+                        help='Path to buildroot tree')
+    parser.add_argument('--out', required=True,
+                        help='Path to buildroot out directory')
+    parser.add_argument('--top-dir', required=True,
+                        help='Replaces %TOP_DIR% in defconfig files')
+    parser.add_argument('--br-ext-optee', required=True,
+                        help='Path the OP-TEE external buildroot tree')
+    parser.add_argument('--br-defconfig', required=True, action='append',
+                        help='Buildroot defconfig file')
+    parser.add_argument('--make-cmd', required=True,
+                        help='Make command')
+    return parser.parse_args()
+
+def concatenate_files(top_dir, dst, srcs):
+	with open(dst, 'w') as outfile:
+	    for fname in srcs:
+		with open(fname) as infile:
+		    for line in infile:
+			outfile.write(line.replace('%TOP_DIR%', top_dir))
+
+def main():
+    args = get_args()
+
+    if not os.path.isdir(args.out):
+        os.makedirs(args.out)
+
+    concatenate_files(args.top_dir, args.out + '/defconfig', args.br_defconfig)
+
+    if os.path.isabs(args.out):
+        out = args.out
+    else:
+        out = '../' + args.out
+
+    if os.path.isabs(args.br_ext_optee):
+        br_ext_optee = args.br_ext_optee
+    else:
+        br_ext_optee = '../' + args.br_ext_optee
+        
+    os.execlp(args.make_cmd, args.make_cmd, '-C', args.br, 'O=' + out,
+              'BR2_EXTERNAL=' + br_ext_optee,
+              'BR2_DEFCONFIG=' + out + '/defconfig', 'defconfig')
+
+if __name__ == "__main__":
+    main()