diff --git a/Makefile b/Makefile
index d9a29bd6510f133a93d527c461c31b17ba13587e..299ff3038703da6ba06365ab7d254bd8320e2969 100644
--- a/Makefile
+++ b/Makefile
@@ -113,6 +113,9 @@ endif
 # Toolchain
 ################################################################################
 
+HOSTCC			:=	gcc
+export HOSTCC
+
 CC			:=	${CROSS_COMPILE}gcc
 CPP			:=	${CROSS_COMPILE}cpp
 AS			:=	${CROSS_COMPILE}gcc
@@ -123,11 +126,21 @@ OD			:=	${CROSS_COMPILE}objdump
 NM			:=	${CROSS_COMPILE}nm
 PP			:=	${CROSS_COMPILE}gcc -E
 
-ASFLAGS_aarch64		=	-mgeneral-regs-only
-TF_CFLAGS_aarch64	=	-mgeneral-regs-only -mstrict-align
+ifeq ($(notdir $(CC)),armclang)
+TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi -march=armv8-a
+TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi -march=armv8-a
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+TF_CFLAGS_aarch32	=	-target armv8a-none-eabi
+TF_CFLAGS_aarch64	=	-target aarch64-elf
+else
+TF_CFLAGS_aarch32	=	-march=armv8-a
+TF_CFLAGS_aarch64	=	-march=armv8-a
+endif
+
+TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
 ASFLAGS_aarch32		=	-march=armv8-a
-TF_CFLAGS_aarch32	=	-march=armv8-a
+ASFLAGS_aarch64		=	-march=armv8-a
 
 CPPFLAGS		=	${DEFINES} ${INCLUDES} -nostdinc		\
 				-Wmissing-include-dirs -Werror
@@ -135,8 +148,8 @@ ASFLAGS			+=	$(CPPFLAGS) $(ASFLAGS_$(ARCH))			\
 				-D__ASSEMBLY__ -ffreestanding 			\
 				-Wa,--fatal-warnings
 TF_CFLAGS		+=	$(CPPFLAGS) $(TF_CFLAGS_$(ARCH))		\
-				-ffreestanding -fno-builtin -Wall -std=c99 -Os	\
-				-ffunction-sections -fdata-sections
+				-ffreestanding -fno-builtin -Wall -std=gnu99	\
+				-Os -ffunction-sections -fdata-sections
 
 LDFLAGS			+=	--fatal-warnings -O1
 LDFLAGS			+=	--gc-sections
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 85ece9305a8af3d7ee768a05c7b8f551c6d414e8..5165000d36ceda71d987f017cfc0a0377d47a785 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -74,6 +74,9 @@ The [Linaro Release Notes][Linaro Release Notes] documents which version of the
 compiler to use for a given Linaro Release. Also, these
 [Linaro instructions][Linaro SW Instructions] provide further guidance.
 
+Optionally, Trusted Firmware can be built using clang or ARM Compiler 6.
+See instructions below on how to switch the default compiler.
+
 In addition, the following optional packages and tools may be needed:
 
 *   `device-tree-compiler` package if you need to rebuild the Flattened Device
@@ -104,6 +107,28 @@ Download the Trusted Firmware source code from Github:
 
         export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
 
+    It is possible to build Trusted Firmware using clang or ARM Compiler 6.
+    To do so `CC` needs to point to the clang or armclang binary. Only the
+    compiler is switched; the assembler and linker need to be provided by
+    the GNU toolchain, thus `CROSS_COMPILE` should be set as described above.
+
+    ARM Compiler 6 will be selected when the base name of the path assigned
+    to `CC` matches the string 'armclang'.
+
+    For AArch64 using ARM Compiler 6:
+
+        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+        make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+
+    Clang will be selected when the base name of the path assigned to `CC`
+    contains the string 'clang'. This is to allow both clang and clang-X.Y
+    to work.
+
+    For AArch64 using clang:
+
+        export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+        make CC=<path-to-clang>/bin/clang PLAT=<platform> all
+
 *   Change to the root directory of the Trusted Firmware source tree and build.
 
     For AArch64:
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index af498ca5f833834ed3959f0ab3ad617fe5035308..e652a59ec631459983d4830f56897caa53854483 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -36,8 +36,8 @@ static inline u_register_t read_ ## _name(void)				\
  *  systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and
  *  Big Endian systems generate the right instruction encoding.
  */
-#if !(__GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
-#error "GCC 4.6 or above is required to build AArch32 Trusted Firmware"
+#if !(__clang__ || __GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
+#error "clang or GCC 4.6 or above is required to build AArch32 Trusted Firmware"
 #endif
 
 #define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm)		\
diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S
index 7ad0bc755961faa64c4ad5bdd1833743bb89fc4a..238455341d4df5ae82c7a52f98c4fa0449e1c1a5 100644
--- a/lib/cpus/aarch64/cpu_helpers.S
+++ b/lib/cpus/aarch64/cpu_helpers.S
@@ -259,8 +259,8 @@ func print_errata_status
 	/*
 	 * Printing errata status requires atomically testing the printed flag.
 	 */
-	stp	x8, x30, [sp, #-16]!
-	mov	x8, x0
+	stp	x19, x30, [sp, #-16]!
+	mov	x19, x0
 
 	/*
 	 * Load pointers to errata lock and printed flag. Call
@@ -270,8 +270,8 @@ func print_errata_status
 	ldr	x0, [x1, #CPU_ERRATA_LOCK]
 	ldr	x1, [x1, #CPU_ERRATA_PRINTED]
 	bl	errata_needs_reporting
-	mov	x1, x8
-	ldp	x8, x30, [sp], #16
+	mov	x1, x19
+	ldp	x19, x30, [sp], #16
 	cbnz	x0, .Lprint
 #endif
 .Lnoprint:
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 391ae45cd6273834b4178667bba23329de7f99ef..5df1cc014f293d80a9eceb664eb86812835888ac 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -12,7 +12,6 @@
 #include <tbbr_oid.h>
 
 /* Weak definition may be overridden in specific platform */
-#pragma weak plat_match_rotpk
 #pragma weak plat_get_nv_ctr
 #pragma weak plat_set_nv_ctr
 
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 449c580f11b39a66e21bf7c9fe2a5c4311f902de..f4df658a7e87eb8c8c8487c602a9dc8eff585206 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -296,8 +296,6 @@ static int fvp_node_hw_state(u_register_t target_cpu,
 	case ARM_PWR_LVL1:
 		ret = (psysr & PSYSR_AFF_L1) ? HW_ON : HW_OFF;
 		break;
-	default:
-		assert(0);
 	}
 
 	return ret;
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index ffec664257068bd0022983d000032988b3846941..e5619b7f4efb2cb7d4b4a75f30598ab848c45e86 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -13,6 +13,7 @@
 #include <desc_image_load.h>
 #include <plat_arm.h>
 #include <platform_def.h>
+#include <platform.h>
 #include <string.h>
 #include <utils.h>
 
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 2369e0cc7cff39183c9c8201a1b22590b065d03c..cc131a9fe81a8d4f8dc82864a51576c895898037 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -122,9 +122,11 @@ int arm_validate_ns_entrypoint(uintptr_t entrypoint)
 	if ((entrypoint >= ARM_NS_DRAM1_BASE) && (entrypoint <
 			(ARM_NS_DRAM1_BASE + ARM_NS_DRAM1_SIZE)))
 		return PSCI_E_SUCCESS;
+#ifndef AARCH32
 	if ((entrypoint >= ARM_DRAM2_BASE) && (entrypoint <
 			(ARM_DRAM2_BASE + ARM_DRAM2_SIZE)))
 		return PSCI_E_SUCCESS;
+#endif
 
 	return PSCI_E_INVALID_ADDRESS;
 }
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 8a216495b744154a476d756d2607d579a6a48fa8..efd1f25d5833f298a9c5c776504f6be7ecd01456 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -64,7 +64,7 @@ INC_DIR := -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include
 LIB_DIR := -L ${OPENSSL_DIR}/lib
 LIB := -lssl -lcrypto
 
-CC := gcc
+HOSTCC ?= gcc
 
 .PHONY: all clean realclean
 
@@ -75,11 +75,11 @@ ${BINARY}: ${OBJECTS} Makefile
 	@echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
                 const char platform_msg[] = "${PLAT_MSG}";' | \
                 ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o
-	${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+	${Q}${HOSTCC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
 
 %.o: %.c
 	@echo "  CC      $<"
-	${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
+	${Q}${HOSTCC} -c ${CFLAGS} ${INC_DIR} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, src/build_msg.o ${OBJECTS})
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 29eac2a7901cd7372b372efac7c41c0b492eba34..ee674b7f9f6660e30b4c5c2b0d9163f77e9d2a7a 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -29,7 +29,7 @@ endif
 
 INCLUDE_PATHS := -I. -I../../include/tools_share
 
-CC := gcc
+HOSTCC ?= gcc
 
 .PHONY: all clean distclean
 
@@ -37,7 +37,7 @@ all: ${PROJECT} fip_create
 
 ${PROJECT}: ${OBJECTS} Makefile
 	@echo "  LD      $@"
-	${Q}${CC} ${OBJECTS} -o $@ ${LDLIBS}
+	${Q}${HOSTCC} ${OBJECTS} -o $@ ${LDLIBS}
 	@${ECHO_BLANK_LINE}
 	@echo "Built $@ successfully"
 	@${ECHO_BLANK_LINE}
@@ -48,7 +48,7 @@ fip_create: fip_create.sh
 
 %.o: %.c %.h Makefile
 	@echo "  CC      $<"
-	${Q}${CC} -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+	${Q}${HOSTCC} -c ${CPPFLAGS} ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
 
 clean:
 	$(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS} fip_create)