diff --git a/CMakeLists.txt b/CMakeLists.txt
index a94f61ab8e8bd5fd87275896a3ef56446283dcd3..34726fc7cf6184560a27c4c7af84041fdcd3d01c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.0)
 
 # project info
 project(cell_algorithms)
@@ -64,13 +64,31 @@ set(NMC_THREADING_MODEL "cthread" CACHE STRING "set the threading model, one of
 set_property(CACHE NMC_THREADING_MODEL PROPERTY STRINGS cthread tbb serial )
 
 if(NMC_THREADING_MODEL MATCHES "tbb")
+    # download and build TBB
+    include(${CMAKE_SOURCE_DIR}/cmake/tbb/TBBGet.cmake)
+    include(${CMAKE_SOURCE_DIR}/cmake/tbb/TBBBuild.cmake)
+    tbb_get(TBB_ROOT tbb_root SOURCE_CODE)
+    tbb_build(TBB_ROOT ${tbb_root} CONFIG_DIR TBB_DIR)
+
+    # configure TBB
+    find_package(TBB REQUIRED tbb tbbmalloc)
 
-    find_package(TBB REQUIRED)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TBB_DEFINITIONS}")
     add_definitions(-DNMC_HAVE_TBB)
     set(NMC_WITH_TBB TRUE)
-    list(APPEND EXTERNAL_LIBRARIES ${TBB_LIBRARIES})
-    list(APPEND EXTERNAL_INCLUDES ${TBB_INCLUDE_DIRS})
+
+    # The TBB CMake package creates the TBB::tbb and TBB:tbbmalloc targets.
+    # The following should be sufficient, however on some systems (e.g. Cray PE),
+    # they don't work (because CMake is fragile):
+    #   list(APPEND EXTERNAL_LIBRARIES TBB::tbb)
+    #   list(APPEND EXTERNAL_LIBRARIES TBB::tbbmalloc)
+    # So, instead, manually add the library links:
+    set(TBB_LIB_PATH ${CMAKE_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release)
+    list(APPEND EXTERNAL_LIBRARIES ${TBB_LIB_PATH}/libtbb.so)
+    list(APPEND EXTERNAL_LIBRARIES ${TBB_LIB_PATH}/libtbbmalloc.so)
+
+    # The TBB headers are in the downloaded TBB source
+    list(APPEND EXTERNAL_INCLUDES ${tbb_root}/include)
+
 elseif(NMC_THREADING_MODEL MATCHES "cthread")
 
     find_package(Threads REQUIRED)
@@ -126,7 +144,10 @@ set_property(CACHE NMC_SYSTEM_TYPE PROPERTY STRINGS Generic Cray BGQ )
 
 # Cray specific flags
 if(${NMC_SYSTEM_TYPE} MATCHES "Cray")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -dynamic")
+    # we no longer set the -dynamic flag for the compilere here, instead dynamic
+    # linking should be enabled by the user by setting the environment variable:
+    #   CRAYPE_LINK_TYPE=dynamic
+    #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -dynamic")
     add_definitions(-DNMC_HAVE_CRAY)
 endif()
 
diff --git a/README.md b/README.md
index e5c991234084a96288999dd8eb3011af79cb013d..e5617e56fb558d79aac7ec154ba476d3f05475b2 100644
--- a/README.md
+++ b/README.md
@@ -57,35 +57,29 @@ When TBB is installed, it comes with some scripts that can be run to set up the
 The scripts set the `TBB_ROOT` environment variable, which is used by the CMake configuration to find TBB.
 
 ```
-source <path to TBB installation>/tbbvars.sh
 cmake <path to CMakeLists.txt> -DNMC_THREADING_MODEL=tbb
 ```
 
 ### TBB on Cray systems
 
-To compile with TBB on Cray systems, load the intel module, which will automatically configure the environment.
-The guide below shows how to use the version of TBB that is installed as part of the Intel compiler toolchain.
-It is recommended that you install the most recent version of TBB yourself, and link against this, because older versions
-of TBB don't work with recent versions of GCC.
+TBB requires dynamic linking, which is not enabled by default in the Cray programming environment.
+CMake is quite brittle, so take care to follow these step closely.
+TBB provides a CMake package that will attempt to automatically download and compile TBB from within CMake.
+Set the environment variable `CRAYPE_LINK_TYPE=dynamic`, to instruct the Cray PE linker to enable dynamic linking.
+CMake (at least since CMake 3.6) will automatically detect the Cray programming environment, and will by default use static linking, unless the `CRAYPE_LINK_TYPE` environment variable has been set to `dynamic`.
+Note, the CMake package provided by TBB is very fragile, and won't work if CMake is forced to use the `CrayLinuxEnvironment` as shown in the code below. Instead, let Cmake automatically detect the programming environment.
 
 ```
-# load the gnu environment for compiling the application
-module load PrgEnv-gnu
-# gcc 5.x does not work with the version of TBB installed on Cray
-# requires at least version 4.4 of TBB
-module swap gcc/4.9.3
-# load the intel programming module
-# on Cray systems this automatically sets `TBB_ROOT` environment variable
-module load intel
-module load cmake
-export CXX=`which CC`
-export CC=`which cc`
+export CRAYPE_LINK_TYPE=dynamic
+cmake <path-to-arbor-source> -DNMC_THREADING_MODEL=tbb
 
-# multithreading only
-cmake <path to CMakeLists.txt> -DNMC_THREADING_MODEL=tbb -DSYSTEM_CRAY=ON
+# NOTE: specifying CMAKE_SYSTEM_NAME won't work, instead let CMake automatically
+# detect the build environment as above.
+cmake <path-to-arbor-source> -DNMC_THREADING_MODEL=tbb  -DCMAKE_SYSTEM_NAME=CrayLinuxEnvironment
+```
 
-# multithreading and MPI
-cmake <path to CMakeLists.txt> -DNMC_THREADING_MODEL=tbb -DNMC_WITH_MPI=ON -DSYSTEM_CRAY=ON
+```
+export CRAYPE_LINK_TYPE=dynamic
 ```
 
 ## targeting KNL
diff --git a/cmake/FindTBB.cmake b/cmake/FindTBB.cmake
deleted file mode 100644
index dadc36616ed2ff1932672308f133f01744d5a394..0000000000000000000000000000000000000000
--- a/cmake/FindTBB.cmake
+++ /dev/null
@@ -1,250 +0,0 @@
-#-----------------------------------------------------------------------------
-# from github justusc/FindTBB
-#-----------------------------------------------------------------------------
-
-# The MIT License (MIT)
-#
-# Copyright (c) 2015 Justus Calvin
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-#
-# FindTBB
-# -------
-#
-# Find TBB include directories and libraries.
-#
-# Usage:
-#
-#  find_package(TBB [major[.minor]] [EXACT]
-#               [QUIET] [REQUIRED]
-#               [[COMPONENTS] [components...]]
-#               [OPTIONAL_COMPONENTS components...]) 
-#
-# where the allowed components are tbbmalloc and tbb_preview. Users may modify 
-# the behavior of this module with the following variables:
-#
-# * TBB_ROOT_DIR          - The base directory the of TBB installation.
-# * TBB_INCLUDE_DIR       - The directory that contains the TBB headers files.
-# * TBB_LIBRARY           - The directory that contains the TBB library files.
-# * TBB_<library>_LIBRARY - The path of the TBB the corresponding TBB library. 
-#                           These libraries, if specified, override the 
-#                           corresponding library search results, where <library>
-#                           may be tbb, tbb_debug, tbbmalloc, tbbmalloc_debug,
-#                           tbb_preview, or tbb_preview_debug.
-# * TBB_USE_DEBUG_BUILD   - The debug version of tbb libraries, if present, will
-#                           be used instead of the release version.
-#
-# Users may modify the behavior of this module with the following environment
-# variables:
-#
-# * TBB_INSTALL_DIR 
-# * TBBROOT
-# * LIBRARY_PATH
-#
-# This module will set the following variables:
-#
-# * TBB_FOUND             - Set to false, or undefined, if we haven’t found, or
-#                           don’t want to use TBB.
-# * TBB_<component>_FOUND - If False, optional <component> part of TBB sytem is
-#                           not available.
-# * TBB_VERSION           - The full version string
-# * TBB_VERSION_MAJOR     - The major version
-# * TBB_VERSION_MINOR     - The minor version
-# * TBB_INTERFACE_VERSION - The interface version number defined in 
-#                           tbb/tbb_stddef.h.
-# * TBB_<library>_LIBRARY_RELEASE - The path of the TBB release version of 
-#                           <library>, where <library> may be tbb, tbb_debug,
-#                           tbbmalloc, tbbmalloc_debug, tbb_preview, or 
-#                           tbb_preview_debug.
-# * TBB_<library>_LIBRARY_DEGUG - The path of the TBB release version of 
-#                           <library>, where <library> may be tbb, tbb_debug,
-#                           tbbmalloc, tbbmalloc_debug, tbb_preview, or 
-#                           tbb_preview_debug.
-#
-# The following varibles should be used to build and link with TBB:
-#
-# * TBB_INCLUDE_DIRS - The include directory for TBB.
-# * TBB_LIBRARIES    - The libraries to link against to use TBB.
-# * TBB_DEFINITIONS  - Definitions to use when compiling code that uses TBB.
-
-include(FindPackageHandleStandardArgs)
-
-if(NOT TBB_FOUND)
-
-  ##################################
-  # Check the build type
-  ##################################
-
-  if(NOT DEFINED TBB_USE_DEBUG_BUILD)
-    if(CMAKE_BUILD_TYPE MATCHES "[Debug|DEBUG|debug|RelWithDebInfo|RELWITHDEBINFO|relwithdebinfo]")
-      set(TBB_USE_DEBUG_BUILD TRUE)
-    else()
-      set(TBB_USE_DEBUG_BUILD FALSE)
-    endif()
-  endif()
-
-  ##################################
-  # Set the TBB search directories
-  ##################################
-
-  # Define search paths based on user input and environment variables
-  set(TBB_SEARCH_DIR ${TBB_ROOT_DIR} $ENV{TBB_INSTALL_DIR} $ENV{TBBROOT})
-
-  # Define the search directories based on the current platform
-  if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
-    set(TBB_DEFAULT_SEARCH_DIR "C:/Program Files/Intel/TBB"
-                               "C:/Program Files (x86)/Intel/TBB")
-
-    # Set the target architecture
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(TBB_ARCHITECTURE "intel64")
-    else()
-      set(TBB_ARCHITECTURE "ia32")
-    endif()
-
-    # Set the TBB search library path search suffix based on the version of VC
-    if(WINDOWS_STORE)
-      set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui")
-    elseif(MSVC14)
-      set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc14")
-    elseif(MSVC12)
-      set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc12")
-    elseif(MSVC11)
-      set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11")
-    elseif(MSVC10)
-      set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10")
-    endif()
-
-    # Add the library path search suffix for the VC independent version of TBB
-    list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt")
-
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-    # OS X
-    set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
-
-    # TODO: Check to see which C++ library is being used by the compiler.
-    if(NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 13.0)
-      # The default C++ library on OS X 10.9 and later is libc++
-      set(TBB_LIB_PATH_SUFFIX "lib/libc++")
-    else()
-      set(TBB_LIB_PATH_SUFFIX "lib")
-    endif()
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-    # Linux
-    set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
-
-    # TODO: Check compiler version to see the suffix should be <arch>/gcc4.1 or
-    #       <arch>/gcc4.1. For now, assume that the compiler is more recent than
-    #       gcc 4.4.x or later.
-    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
-      set(TBB_LIB_PATH_SUFFIX "lib/intel64/gcc4.4")
-    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
-      set(TBB_LIB_PATH_SUFFIX "lib/ia32/gcc4.4")
-    endif()
-    list(APPEND TBB_LIB_PATH_SUFFIX "lib")
-  endif()
-
-  ##################################
-  # Find the TBB include dir
-  ##################################
-
-  find_path(TBB_INCLUDE_DIRS tbb/tbb.h
-      HINTS ${TBB_INCLUDE_DIR} ${TBB_SEARCH_DIR}
-      PATHS ${TBB_DEFAULT_SEARCH_DIR}
-      PATH_SUFFIXES include)
-
-  ##################################
-  # Find TBB components
-  ##################################
-
-  # Find each component
-  foreach(_comp tbb_preview tbbmalloc tbb)
-    # Search for the libraries
-    find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}
-        HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
-        PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
-        PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
-
-    find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}_debug
-        HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
-        PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
-        PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
-
-
-    # Set the library to be used for the component
-    if(NOT TBB_${_comp}_LIBRARY)
-      if(TBB_USE_DEBUG_BUILD AND TBB_${_comp}_LIBRARY_DEBUG)
-        set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_DEBUG}")
-      elseif(TBB_${_comp}_LIBRARY_RELEASE)
-        set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_RELEASE}")
-      elseif(TBB_${_comp}_LIBRARY_DEBUG)
-        set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_DEBUG}")
-      endif()
-    endif()
-
-    # Set the TBB library list and component found variables
-    if(TBB_${_comp}_LIBRARY)
-      list(APPEND TBB_LIBRARIES "${TBB_${_comp}_LIBRARY}")
-      set(TBB_${_comp}_FOUND TRUE)
-    else()
-      set(TBB_${_comp}_FOUND FALSE)
-    endif()
-
-    mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE)
-    mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG)
-    mark_as_advanced(TBB_${_comp}_LIBRARY)
-
-  endforeach()
-
-  ##################################
-  # Set compile flags
-  ##################################
-
-  if(TBB_tbb_LIBRARY MATCHES "debug")
-    set(TBB_DEFINITIONS "-DTBB_USE_DEBUG=1")
-  endif()
-
-  ##################################
-  # Set version strings
-  ##################################
-
-  if(TBB_INCLUDE_DIRS)
-    file(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _tbb_version_file)
-    string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
-            TBB_VERSION_MAJOR "${_tbb_version_file}")
-    string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
-            TBB_VERSION_MINOR "${_tbb_version_file}")
-    string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
-            TBB_INTERFACE_VERSION "${_tbb_version_file}")
-    set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}")
-  endif()
-
-  find_package_handle_standard_args(TBB 
-      REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES
-      HANDLE_COMPONENTS
-      VERSION_VAR TBB_VERSION)
-
-  mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES)
-
-  unset(TBB_ARCHITECTURE)
-  unset(TBB_LIB_PATH_SUFFIX)
-  unset(TBB_DEFAULT_SEARCH_DIR)
-
-endif()
diff --git a/cmake/tbb/TBBBuild.cmake b/cmake/tbb/TBBBuild.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bcf04c87bf23755911d5955ec844fb1eff9b0a5b
--- /dev/null
+++ b/cmake/tbb/TBBBuild.cmake
@@ -0,0 +1,197 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+#
+# Usage:
+#  include(TBBBuild.cmake)
+#  tbb_build(ROOT <tbb_root> MAKE_ARGS <arg1> [... <argN>])
+#  find_package(TBB <options>)
+#
+
+include(CMakeParseArguments)
+
+# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions,
+# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html
+set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR})
+
+##
+# Builds Intel TBB.
+#
+# Parameters:
+#  TBB_ROOT   <directory> - path to Intel TBB root directory (with sources);
+#  MAKE_ARGS  <list>      - user-defined arguments to be passed to make-tool;
+#  CONFIG_DIR <variable>  - store location of the created TBBConfig if the build was ok, store <variable>-NOTFOUND otherwise.
+#
+function(tbb_build)
+    # NOTE: internal function are used to hide them from user.
+
+    ##
+    # Provides arguments for make-command to build Intel TBB.
+    #
+    # Following arguments are provided automatically if they are not defined by user:
+    #  compiler=<value>
+    #  tbb_build_dir=<value>
+    #  tbb_build_prefix=<value>
+    #  -j<n>
+    #
+    # Parameters:
+    #  USER_DEFINED_ARGS <list> - list of user-defined arguments;
+    #  RESULT <variable> - resulting list of 'make' arguments.
+    #
+    function(tbb_get_make_args)
+        set(oneValueArgs RESULT)
+        set(multiValueArgs USER_DEFINED_ARGS)
+        cmake_parse_arguments(tbb_GMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+        set(result ${tbb_GMA_USER_DEFINED_ARGS})
+
+        if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "compiler=")
+            # TODO: add other supported compilers.
+            if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+                set(compiler gcc)
+            elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
+                set(compiler icc)
+                if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+                    set(compiler icl)
+                endif()
+            elseif (MSVC)
+                set(compiler cl)
+            elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+                set(compiler clang)
+            endif()
+
+            set(result "compiler=${compiler}" ${result})
+        endif()
+
+        if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "tbb_build_dir=")
+            set(result "tbb_build_dir=${CMAKE_CURRENT_BINARY_DIR}/tbb_cmake_build" ${result})
+        endif()
+
+        if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "tbb_build_prefix=")
+            set(result "tbb_build_prefix=tbb_cmake_build_subdir" ${result})
+        endif()
+
+        if (NOT tbb_GMA_USER_DEFINED_ARGS MATCHES "(;|^) *\\-j[0-9]* *(;|$)")
+            include(ProcessorCount)
+            ProcessorCount(num_of_cores)
+            if (NOT num_of_cores EQUAL 0)
+                set(result "-j${num_of_cores}" ${result})
+            endif()
+        endif()
+
+        if (CMAKE_SYSTEM_NAME MATCHES "Android")
+            set(result target=android ${result})
+        endif()
+
+        set(${tbb_GMA_RESULT} ${result} PARENT_SCOPE)
+    endfunction()
+
+    ##
+    # Provides release and debug directories basing on 'make' arguments.
+    #
+    # Following 'make' arguments are parsed: tbb_build_dir, tbb_build_prefix
+    #
+    # Parameters:
+    #  MAKE_ARGS   <list>     - 'make' arguments (tbb_build_dir and tbb_build_prefix are required)
+    #  RELEASE_DIR <variable> - store normalized (CMake) path to release directory
+    #  DEBUG_DIR   <variable> - store normalized (CMake) path to debug directory
+    #
+    function(tbb_get_build_paths_from_make_args)
+        set(oneValueArgs RELEASE_DIR DEBUG_DIR)
+        set(multiValueArgs MAKE_ARGS)
+        cmake_parse_arguments(tbb_GBPFMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+        foreach(arg ${tbb_GBPFMA_MAKE_ARGS})
+            if (arg MATCHES "tbb_build_dir=")
+                string(REPLACE "tbb_build_dir=" "" tbb_build_dir "${arg}")
+            elseif (arg MATCHES "tbb_build_prefix=")
+                string(REPLACE "tbb_build_prefix=" "" tbb_build_prefix "${arg}")
+            endif()
+        endforeach()
+
+        set(tbb_release_dir "${tbb_build_dir}/${tbb_build_prefix}_release")
+        set(tbb_debug_dir "${tbb_build_dir}/${tbb_build_prefix}_debug")
+
+        file(TO_CMAKE_PATH "${tbb_release_dir}" tbb_release_dir)
+        file(TO_CMAKE_PATH "${tbb_debug_dir}" tbb_debug_dir)
+
+        set(${tbb_GBPFMA_RELEASE_DIR} ${tbb_release_dir} PARENT_SCOPE)
+        set(${tbb_GBPFMA_DEBUG_DIR} ${tbb_debug_dir} PARENT_SCOPE)
+    endfunction()
+
+    # -------------------- #
+    # Function entry point #
+    # -------------------- #
+    set(oneValueArgs TBB_ROOT CONFIG_DIR)
+    set(multiValueArgs MAKE_ARGS)
+    cmake_parse_arguments(tbb_build "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    if (NOT EXISTS "${tbb_build_TBB_ROOT}/Makefile" OR NOT EXISTS "${tbb_build_TBB_ROOT}/src")
+        message(STATUS "Intel TBB can not be built: Makefile or src directory was not found in ${tbb_build_TBB_ROOT}")
+        set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    set(make_tool_name make)
+    if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+        set(make_tool_name gmake)
+    elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
+        set(make_tool_name ndk-build)
+    endif()
+
+    find_program(TBB_MAKE_TOOL ${make_tool_name} DOC "Make-tool to build Intel TBB.")
+    mark_as_advanced(TBB_MAKE_TOOL)
+
+    if (NOT TBB_MAKE_TOOL)
+        message(STATUS "Intel TBB can not be built: required make-tool (${make_tool_name}) was not found")
+        set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    tbb_get_make_args(USER_DEFINED_ARGS ${tbb_build_MAKE_ARGS} RESULT tbb_make_args)
+
+    set(tbb_build_cmd ${TBB_MAKE_TOOL} ${tbb_make_args})
+
+    string(REPLACE ";" " " tbb_build_cmd_str "${tbb_build_cmd}")
+    message(STATUS "Building Intel TBB: ${tbb_build_cmd_str}")
+    execute_process(COMMAND ${tbb_build_cmd}
+                    WORKING_DIRECTORY ${tbb_build_TBB_ROOT}
+                    RESULT_VARIABLE tbb_build_result
+                    ERROR_VARIABLE tbb_build_error_output
+                    OUTPUT_QUIET)
+
+    if (NOT tbb_build_result EQUAL 0)
+        message(STATUS "Building is unsuccessful (${tbb_build_result}): ${tbb_build_error_output}")
+        set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    tbb_get_build_paths_from_make_args(MAKE_ARGS ${tbb_make_args}
+                                       RELEASE_DIR tbb_release_dir
+                                       DEBUG_DIR tbb_debug_dir)
+
+    include(${_tbb_cmake_module_path}/TBBMakeConfig.cmake)
+    tbb_make_config(TBB_ROOT ${tbb_build_TBB_ROOT}
+                    SYSTEM_NAME ${CMAKE_SYSTEM_NAME}
+                    CONFIG_DIR tbb_config_dir
+                    CONFIG_FOR_SOURCE
+                    TBB_RELEASE_DIR ${tbb_release_dir}
+                    TBB_DEBUG_DIR ${tbb_debug_dir})
+
+    set(${tbb_build_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/tbb/TBBGet.cmake b/cmake/tbb/TBBGet.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..4f595d2399913cb1eda1768395bc3bdcc98629b1
--- /dev/null
+++ b/cmake/tbb/TBBGet.cmake
@@ -0,0 +1,298 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+include(CMakeParseArguments)
+
+# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions,
+# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html
+set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR})
+
+##
+# Downloads file.
+#
+# Parameters:
+#  URL     <url>      - URL to download data from;
+#  SAVE_AS <filename> - filename there to save downloaded data;
+#  INFO    <string>   - text description of content to be downloaded;
+#                       will be printed as message in format is "Downloading <INFO>: <URL>;
+#  FORCE              - option to delete local file from SAVE_AS if it exists;
+#
+function(_tbb_download_file)
+    set(options FORCE)
+    set(oneValueArgs URL RELEASE SAVE_AS INFO)
+    cmake_parse_arguments(tbb_df "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    if (tbb_df_FORCE AND EXISTS "${tbb_df_SAVE_AS}")
+        file(REMOVE ${tbb_df_SAVE_AS})
+    endif()
+
+    if (NOT EXISTS "${tbb_df_SAVE_AS}")
+        set(_show_progress)
+        if (TBB_DOWNLOADING_PROGRESS)
+            set(_show_progress SHOW_PROGRESS)
+        endif()
+
+        message(STATUS "Downloading ${tbb_df_INFO}: ${tbb_df_URL}")
+        file(DOWNLOAD ${tbb_df_URL} ${tbb_df_SAVE_AS} ${_show_progress} STATUS download_status)
+
+        list(GET download_status 0 download_status_num)
+        if (NOT download_status_num EQUAL 0)
+            message(STATUS "Unsuccessful downloading: ${download_status}")
+            file(REMOVE ${tbb_df_SAVE_AS})
+            return()
+        endif()
+    else()
+        message(STATUS "Needed file was found locally ${tbb_df_SAVE_AS}. Remove it if you still want to download a new one")
+    endif()
+endfunction()
+
+##
+# Checks if specified Intel TBB release is available on GitHub.
+#
+# tbb_check_git_release(<release> <result>)
+# Parameters:
+#  <release_tag> - release to be checked;
+#  <result>  - store result (TRUE/FALSE).
+#
+function(_tbb_check_git_release_tag _tbb_release_tag _tbb_release_tag_avail)
+    if (_tbb_release_tag STREQUAL LATEST)
+        set(${_tbb_release_tag_avail} TRUE PARENT_SCOPE)
+        return()
+    endif()
+
+    set(tbb_releases_file "${CMAKE_CURRENT_BINARY_DIR}/tbb_releases.json")
+
+    _tbb_download_file(URL     "${tbb_github_api}/releases"
+                       SAVE_AS ${tbb_releases_file}
+                       INFO    "information from GitHub about Intel TBB releases"
+                       FORCE)
+
+    if (NOT EXISTS "${tbb_releases_file}")
+        set(${_tbb_release_tag_avail} FALSE PARENT_SCOPE)
+        return()
+    endif()
+
+    file(READ ${tbb_releases_file} tbb_releases)
+
+    string(REPLACE "\"" "" tbb_releases ${tbb_releases})
+    string(REGEX MATCHALL "tag_name: *([A-Za-z0-9_\\.]+)" tbb_releases ${tbb_releases})
+
+    set(_release_available FALSE)
+    foreach(tbb_rel ${tbb_releases})
+        string(REGEX REPLACE "tag_name: *" "" tbb_rel_cut ${tbb_rel})
+        list(REMOVE_ITEM tbb_releases ${tbb_rel})
+        list(APPEND tbb_releases ${tbb_rel_cut})
+        if (_tbb_release_tag STREQUAL tbb_rel_cut)
+            set(_release_available TRUE)
+            break()
+        endif()
+    endforeach()
+
+    if (NOT _release_available)
+        string(REPLACE ";" ", " tbb_releases_str "${tbb_releases}")
+        message(STATUS "Requested release tag ${_tbb_release_tag} is not available. Available Intel TBB release tags: ${tbb_releases_str}")
+    endif()
+
+    set(${_tbb_release_tag_avail} ${_release_available} PARENT_SCOPE)
+endfunction()
+
+##
+# Compares two Intel TBB releases and provides result
+# TRUE if the first release is less than the second, FALSE otherwise.
+#
+# tbb_is_release_less(<rel1> <rel2> <result>)
+#
+function(_tbb_is_release_less rel1 rel2 result)
+    # Convert release to numeric representation to compare it using "if" with VERSION_LESS.
+    string(REGEX REPLACE "[A-Za-z]" "" rel1 "${rel1}")
+    string(REPLACE "_" "." rel1 "${rel1}")
+    string(REGEX REPLACE "[A-Za-z]" "" rel2 "${rel2}")
+    string(REPLACE "_" "." rel2 "${rel2}")
+
+    if (${rel1} VERSION_LESS ${rel2})
+        set(${result} TRUE PARENT_SCOPE)
+        return()
+    endif()
+
+    set(${result} FALSE PARENT_SCOPE)
+endfunction()
+
+##
+# Finds exact URL to download Intel TBB basing on provided parameters.
+#
+# Usage:
+#  _tbb_get_url(URL <var_to_save_url> RELEASE_TAG <release_tag|LATEST> OS <os> [SOURCE_CODE])
+#
+function(_tbb_get_url)
+    set(oneValueArgs URL RELEASE_TAG OS)
+    set(options SOURCE_CODE)
+    cmake_parse_arguments(tbb_get_url "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    set(tbb_github_api "https://api.github.com/repos/01org/tbb")
+
+    _tbb_check_git_release_tag(${tbb_get_url_RELEASE_TAG} tbb_release_available)
+    if (NOT tbb_release_available)
+        set(${tbb_download_FULL_PATH} ${tbb_download_FULL_PATH}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    if (tbb_get_url_RELEASE_TAG STREQUAL LATEST)
+        set(tbb_rel_info_api_url "${tbb_github_api}/releases/latest")
+    else()
+        set(tbb_rel_info_api_url "${tbb_github_api}/releases/tags/${tbb_get_url_RELEASE_TAG}")
+    endif()
+
+    set(tbb_release_info_file "${CMAKE_CURRENT_BINARY_DIR}/tbb_${tbb_get_url_RELEASE_TAG}_info.json")
+
+    _tbb_download_file(URL     ${tbb_rel_info_api_url}
+                       SAVE_AS ${tbb_release_info_file}
+                       INFO    "information from GitHub about packages for Intel TBB ${tbb_get_url_RELEASE_TAG}"
+                       FORCE)
+
+    if (NOT EXISTS "${tbb_release_info_file}")
+        set(${tbb_get_url_URL} ${tbb_get_url_URL}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    file(STRINGS ${tbb_release_info_file} tbb_release_info)
+
+    if (tbb_get_url_SOURCE_CODE)
+        # Find name of the latest release to get link to source archive.
+        if (tbb_get_url_RELEASE_TAG STREQUAL LATEST)
+            string(REPLACE "\"" "" tbb_release_info ${tbb_release_info})
+            string(REGEX REPLACE ".*tag_name: *([A-Za-z0-9_\\.]+).*" "\\1" tbb_get_url_RELEASE_TAG "${tbb_release_info}")
+        endif()
+
+        set(${tbb_get_url_URL} "https://github.com/01org/tbb/archive/${tbb_get_url_RELEASE_TAG}.tar.gz" PARENT_SCOPE)
+    else()
+        if (tbb_get_url_OS MATCHES "Linux")
+            set(tbb_lib_archive_suffix lin.tgz)
+        elseif (tbb_get_url_OS MATCHES "Windows")
+            set(tbb_lib_archive_suffix win.zip)
+        elseif (tbb_get_url_OS MATCHES "Darwin")
+            set(tbb_lib_archive_suffix mac.tgz)
+
+            # Since 2017_U4 release archive for Apple has suffix "mac.tgz" instead of "osx.tgz".
+            if (NOT tbb_get_url_RELEASE_TAG STREQUAL "LATEST")
+                _tbb_is_release_less(${tbb_get_url_RELEASE_TAG} 2017_U4 release_less)
+                if (release_less)
+                    set(tbb_lib_archive_suffix osx.tgz)
+                endif()
+            endif()
+        elseif (tbb_get_url_OS MATCHES "Android")
+            set(tbb_lib_archive_suffix and.tgz)
+        else()
+            message(STATUS "Currently prebuilt Intel TBB is not available for your OS (${tbb_get_url_OS})")
+            set(${tbb_get_url_URL} ${tbb_get_url_URL}-NOTFOUND PARENT_SCOPE)
+            return()
+        endif()
+
+        string(REGEX REPLACE ".*(https.*oss_${tbb_lib_archive_suffix}).*" "\\1" tbb_bin_url "${tbb_release_info}")
+
+        set(${tbb_get_url_URL} ${tbb_bin_url} PARENT_SCOPE)
+    endif()
+endfunction()
+
+function(tbb_get)
+    set(oneValueArgs RELEASE_TAG SYSTEM_NAME SAVE_TO TBB_ROOT CONFIG_DIR)
+    set(options SOURCE_CODE)
+    cmake_parse_arguments(tbb_get "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    set(tbb_os ${CMAKE_SYSTEM_NAME})
+    if (tbb_get_SYSTEM_NAME)
+        set(tbb_os ${tbb_get_SYSTEM_NAME})
+    endif()
+
+    set(tbb_release_tag LATEST)
+    if (tbb_get_RELEASE_TAG)
+        set(tbb_release_tag ${tbb_get_RELEASE_TAG})
+    endif()
+
+    set(tbb_save_to ${CMAKE_CURRENT_BINARY_DIR}/tbb_downloaded)
+    if (tbb_get_SAVE_TO)
+        set(tbb_save_to ${tbb_get_SAVE_TO})
+    endif()
+
+    if (tbb_get_SOURCE_CODE)
+        _tbb_get_url(URL tbb_url RELEASE_TAG ${tbb_release_tag} OS ${tbb_os} SOURCE_CODE)
+    else()
+        _tbb_get_url(URL tbb_url RELEASE_TAG ${tbb_release_tag} OS ${tbb_os})
+    endif()
+
+    if (NOT tbb_url)
+        message(STATUS "URL to download Intel TBB has not been found")
+        set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    get_filename_component(filename ${tbb_url} NAME)
+    set(local_file "${CMAKE_CURRENT_BINARY_DIR}/${filename}")
+
+    _tbb_download_file(URL     ${tbb_url}
+                       SAVE_AS ${local_file}
+                       INFO    "Intel TBB library")
+
+    if (NOT EXISTS "${local_file}")
+        set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    get_filename_component(subdir_name ${filename} NAME_WE)
+    file(MAKE_DIRECTORY ${tbb_save_to}/${subdir_name})
+    if (NOT EXISTS "${tbb_save_to}/${subdir_name}")
+        message(STATUS "${tbb_save_to}/${subdir_name} can not be created")
+        set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    message(STATUS "Unpacking ${local_file} to ${tbb_save_to}/${subdir_name}")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf ${local_file}
+                    WORKING_DIRECTORY ${tbb_save_to}/${subdir_name}
+                    RESULT_VARIABLE unpacking_result)
+
+    if (NOT unpacking_result EQUAL 0)
+        message(STATUS "Unsuccessful unpacking: ${unpacking_result}")
+        set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    file(GLOB_RECURSE tbb_h ${tbb_save_to}/${subdir_name}/*/include/tbb/tbb.h)
+    list(GET tbb_h 0 tbb_h)
+
+    if (NOT EXISTS "${tbb_h}")
+        message(STATUS "tbb/tbb.h has not been found in the downloaded package")
+        set(${tbb_get_TBB_ROOT} ${tbb_get_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
+        return()
+    endif()
+
+    get_filename_component(tbb_root "${tbb_h}" PATH)
+    get_filename_component(tbb_root "${tbb_root}" PATH)
+    get_filename_component(tbb_root "${tbb_root}" PATH)
+
+    if (NOT tbb_get_SOURCE_CODE)
+        set(tbb_config_dir ${tbb_root}/cmake)
+
+        if (NOT EXISTS "${tbb_config_dir}")
+            tbb_make_config(TBB_ROOT ${tbb_root} CONFIG_DIR tbb_config_dir)
+        endif()
+
+        set(${tbb_get_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE)
+    endif()
+
+    set(${tbb_get_TBB_ROOT} ${tbb_root} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/tbb/TBBMakeConfig.cmake b/cmake/tbb/TBBMakeConfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6d25db0c94e1357a00f656a03c59a34b1c308f1a
--- /dev/null
+++ b/cmake/tbb/TBBMakeConfig.cmake
@@ -0,0 +1,162 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+#
+# Usage:
+#   include(TBBMakeConfig.cmake)
+#   tbb_make_config(TBB_ROOT <tbb_root> SYSTEM_NAME <system_name> CONFIG_DIR <var_to_store_config_dir> [CONFIG_FOR_SOURCE TBB_RELEASE_DIR <tbb_release_dir> TBB_DEBUG_DIR <tbb_debug_dir>])
+#
+
+include(CMakeParseArguments)
+
+# Save the location of Intel TBB CMake modules here, as it will not be possible to do inside functions,
+# see for details: https://cmake.org/cmake/help/latest/variable/CMAKE_CURRENT_LIST_DIR.html
+set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR})
+
+function(tbb_make_config)
+    set(oneValueArgs TBB_ROOT SYSTEM_NAME CONFIG_DIR TBB_RELEASE_DIR TBB_DEBUG_DIR)
+    set(options CONFIG_FOR_SOURCE)
+    cmake_parse_arguments(tbb_MK "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+    set(tbb_system_name ${CMAKE_SYSTEM_NAME})
+    if (tbb_MK_SYSTEM_NAME)
+        set(tbb_system_name ${tbb_MK_SYSTEM_NAME})
+    endif()
+
+    file(MAKE_DIRECTORY ${tbb_MK_TBB_ROOT}/cmake)
+
+    set(TBB_DEFAULT_COMPONENTS tbb tbbmalloc tbbmalloc_proxy)
+
+    if (tbb_MK_CONFIG_FOR_SOURCE)
+        set(TBB_RELEASE_DIR ${tbb_MK_TBB_RELEASE_DIR})
+        set(TBB_DEBUG_DIR ${tbb_MK_TBB_DEBUG_DIR})
+    endif()
+
+    if (tbb_system_name STREQUAL "Linux")
+        set(TBB_SHARED_LIB_DIR "lib")
+        set(TBB_X32_SUBDIR "ia32")
+        set(TBB_X64_SUBDIR "intel64")
+        set(TBB_LIB_PREFIX "lib")
+        set(TBB_LIB_EXT "so.2")
+
+        # Note: multiline variable
+        set(TBB_CHOOSE_COMPILER_SUBDIR "if (CMAKE_CXX_COMPILER_LOADED)
+    set(_tbb_compiler_id \${CMAKE_CXX_COMPILER_ID})
+    set(_tbb_compiler_ver \${CMAKE_CXX_COMPILER_VERSION})
+elseif (CMAKE_C_COMPILER_LOADED)
+    set(_tbb_compiler_id \${CMAKE_C_COMPILER_ID})
+    set(_tbb_compiler_ver \${CMAKE_C_COMPILER_VERSION})
+endif()
+
+# For non-GCC compilers try to find version of system GCC to choose right compiler subdirectory.
+if (NOT _tbb_compiler_id STREQUAL \"GNU\")
+    execute_process(COMMAND gcc --version OUTPUT_VARIABLE _tbb_gcc_ver_output ERROR_QUIET)
+    string(REGEX REPLACE \".*gcc.*([0-9]+\\\\.[0-9]+)\\\\.[0-9]+.*\" \"\\\\1\" _tbb_compiler_ver \"\${_tbb_gcc_ver_output}\")
+    if (NOT _tbb_compiler_ver)
+        message(FATAL_ERROR \"This Intel TBB package is intended to be used only environment with available 'gcc'\")
+    endif()
+    unset(_tbb_gcc_ver_output)
+endif()
+
+set(_tbb_compiler_subdir gcc4.1)
+foreach (_tbb_gcc_version 4.1 4.4 4.7)
+    if (NOT _tbb_compiler_ver VERSION_LESS \${_tbb_gcc_version})
+        set(_tbb_compiler_subdir gcc\${_tbb_gcc_version})
+    endif()
+endforeach()
+
+unset(_tbb_compiler_id)
+unset(_tbb_compiler_ver)")
+
+    elseif (tbb_system_name STREQUAL "Windows")
+        set(TBB_SHARED_LIB_DIR "bin")
+        set(TBB_X32_SUBDIR "ia32")
+        set(TBB_X64_SUBDIR "intel64")
+        set(TBB_LIB_PREFIX "")
+        set(TBB_LIB_EXT "dll")
+
+        # Note: multiline variable
+        set(TBB_CHOOSE_COMPILER_SUBDIR "if (NOT MSVC)
+    message(FATAL_ERROR \"This Intel TBB package is intended to be used only in the project with MSVC\")
+endif()
+
+# Detect the most relevant MSVC subdirectory
+set(_tbb_msvc_1700_subdir vc11)
+set(_tbb_msvc_1800_subdir vc12)
+set(_tbb_msvc_1900_subdir vc14)
+set(_tbb_msvc_ver \${MSVC_VERSION})
+if (MSVC_VERSION VERSION_LESS 1700)
+    message(FATAL_ERROR \"This Intel TBB package is intended to be used only in the project with MSVC version 1700 (vc11) or higher\")
+elseif (MSVC_VERSION VERSION_GREATER 1900)
+    set(_tbb_msvc_ver 1900)
+endif()
+set(_tbb_compiler_subdir \${_tbb_msvc_\${_tbb_msvc_ver}_subdir})
+unset(_tbb_msvc_1700_subdir)
+unset(_tbb_msvc_1800_subdir)
+unset(_tbb_msvc_1900_subdir)
+
+if (WINDOWS_STORE)
+    set(_tbb_compiler_subdir \${_tbb_compiler_subdir}_ui)
+endif()")
+
+        if (tbb_MK_CONFIG_FOR_SOURCE)
+            set(TBB_IMPLIB_RELEASE "\nIMPORTED_IMPLIB_RELEASE \"${tbb_MK_TBB_RELEASE_DIR}/\${_tbb_component}.lib\"")
+            set(TBB_IMPLIB_DEBUG "\nIMPORTED_IMPLIB_DEBUG \"${tbb_MK_TBB_DEBUG_DIR}/\${_tbb_component}_debug.lib\"")
+        else()
+            # Note: multiline variable
+            set(TBB_IMPLIB "
+                              IMPORTED_IMPLIB_RELEASE       \"\${_tbb_root}/lib/\${_tbb_arch_subdir}/\${_tbb_compiler_subdir}/\${_tbb_component}.lib\"
+                              IMPORTED_IMPLIB_DEBUG         \"\${_tbb_root}/lib/\${_tbb_arch_subdir}/\${_tbb_compiler_subdir}/\${_tbb_component}_debug.lib\"")
+        endif()
+
+        # Note: multiline variable
+        # tbb/internal/_tbb_windef.h (included via tbb/tbb_stddef.h) does implicit linkage of some .lib files, use a special define to avoid it
+        set(TBB_COMPILE_DEFINITIONS "
+                              INTERFACE_COMPILE_DEFINITIONS \"__TBB_NO_IMPLICIT_LINKAGE=1\"")
+    elseif (tbb_system_name STREQUAL "Darwin")
+        set(TBB_SHARED_LIB_DIR "lib")
+        set(TBB_X32_SUBDIR ".")
+        set(TBB_X64_SUBDIR ".")
+        set(TBB_LIB_PREFIX "lib")
+        set(TBB_LIB_EXT "dylib")
+        set(TBB_CHOOSE_COMPILER_SUBDIR "set(_tbb_compiler_subdir .)")
+    elseif (tbb_system_name STREQUAL "Android")
+        set(TBB_SHARED_LIB_DIR "lib")
+        set(TBB_X32_SUBDIR ".")
+        set(TBB_X64_SUBDIR "x86_64")
+        set(TBB_LIB_PREFIX "lib")
+        set(TBB_LIB_EXT "so")
+        set(TBB_CHOOSE_COMPILER_SUBDIR "set(_tbb_compiler_subdir .)")
+    endif()
+
+    file(READ "${tbb_MK_TBB_ROOT}/include/tbb/tbb_stddef.h" _tbb_stddef)
+    string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" _tbb_ver_major "${_tbb_stddef}")
+    string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" _tbb_ver_minor "${_tbb_stddef}")
+    string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_tbb_stddef}")
+    set(TBB_VERSION "${_tbb_ver_major}.${_tbb_ver_minor}")
+
+    if (tbb_MK_CONFIG_FOR_SOURCE)
+        set(_tbb_config_template TBBConfigForSource.cmake.in)
+    else()
+        set(_tbb_config_template TBBConfig.cmake.in)
+    endif()
+    configure_file(${_tbb_cmake_module_path}/templates/${_tbb_config_template}   ${tbb_MK_TBB_ROOT}/cmake/TBBConfig.cmake @ONLY)
+    configure_file(${_tbb_cmake_module_path}/templates/TBBConfigVersion.cmake.in ${tbb_MK_TBB_ROOT}/cmake/TBBConfigVersion.cmake @ONLY)
+
+    set(${tbb_MK_CONFIG_DIR} ${tbb_MK_TBB_ROOT}/cmake PARENT_SCOPE)
+endfunction()
diff --git a/cmake/tbb/templates/TBBConfig.cmake.in b/cmake/tbb/templates/TBBConfig.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..19bc1fca89b97f8387286899d27a73e1a4a87b3c
--- /dev/null
+++ b/cmake/tbb/templates/TBBConfig.cmake.in
@@ -0,0 +1,89 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+# TBB_FOUND should not be set explicitly. It is defined automatically by CMake.
+# Handling of TBB_VERSION is in TBBConfigVersion.cmake.
+
+if (NOT TBB_FIND_COMPONENTS)
+    set(TBB_FIND_COMPONENTS "@TBB_DEFAULT_COMPONENTS@")
+    foreach (_tbb_component ${TBB_FIND_COMPONENTS})
+        set(TBB_FIND_REQUIRED_${_tbb_component} 1)
+    endforeach()
+endif()
+
+# Add components with internal dependencies: tbbmalloc_proxy -> tbbmalloc
+list(FIND TBB_FIND_COMPONENTS tbbmalloc_proxy _tbbmalloc_proxy_ix)
+if (NOT _tbbmalloc_proxy_ix EQUAL -1)
+    list(FIND TBB_FIND_COMPONENTS tbbmalloc _tbbmalloc_ix)
+    if (_tbbmalloc_ix EQUAL -1)
+        list(APPEND TBB_FIND_COMPONENTS tbbmalloc)
+        set(TBB_FIND_REQUIRED_tbbmalloc ${TBB_FIND_REQUIRED_tbbmalloc_proxy})
+    endif()
+endif()
+
+set(TBB_INTERFACE_VERSION @TBB_INTERFACE_VERSION@)
+
+get_filename_component(_tbb_root "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_tbb_root "${_tbb_root}" PATH)
+
+set(_tbb_x32_subdir @TBB_X32_SUBDIR@)
+set(_tbb_x64_subdir @TBB_X64_SUBDIR@)
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(_tbb_arch_subdir ${_tbb_x64_subdir})
+else()
+    set(_tbb_arch_subdir ${_tbb_x32_subdir})
+endif()
+
+@TBB_CHOOSE_COMPILER_SUBDIR@
+
+get_filename_component(_tbb_lib_path "${_tbb_root}/@TBB_SHARED_LIB_DIR@/${_tbb_arch_subdir}/${_tbb_compiler_subdir}" ABSOLUTE)
+
+foreach (_tbb_component ${TBB_FIND_COMPONENTS})
+    set(_tbb_release_lib "${_tbb_lib_path}/@TBB_LIB_PREFIX@${_tbb_component}.@TBB_LIB_EXT@")
+    set(_tbb_debug_lib "${_tbb_lib_path}/@TBB_LIB_PREFIX@${_tbb_component}_debug.@TBB_LIB_EXT@")
+
+    if (EXISTS "${_tbb_release_lib}" AND EXISTS "${_tbb_debug_lib}")
+        add_library(TBB::${_tbb_component} SHARED IMPORTED)
+        set_target_properties(TBB::${_tbb_component} PROPERTIES
+                              IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
+                              IMPORTED_LOCATION_RELEASE     "${_tbb_release_lib}"
+                              IMPORTED_LOCATION_DEBUG       "${_tbb_debug_lib}"
+                              INTERFACE_INCLUDE_DIRECTORIES "${_tbb_root}/include"@TBB_IMPLIB@@TBB_COMPILE_DEFINITIONS@)
+
+        # Add internal dependencies for imported targets: TBB::tbbmalloc_proxy -> TBB::tbbmalloc
+        if (_tbb_component STREQUAL tbbmalloc_proxy)
+            set_target_properties(TBB::tbbmalloc_proxy PROPERTIES INTERFACE_LINK_LIBRARIES TBB::tbbmalloc)
+        endif()
+
+        list(APPEND TBB_IMPORTED_TARGETS TBB::${_tbb_component})
+        set(TBB_${_tbb_component}_FOUND 1)
+    elseif (TBB_FIND_REQUIRED AND TBB_FIND_REQUIRED_${_tbb_component})
+        message(FATAL_ERROR "Missed required Intel TBB component: ${_tbb_component}")
+    endif()
+endforeach()
+
+unset(_tbb_x32_subdir)
+unset(_tbb_x64_subdir)
+unset(_tbb_arch_subdir)
+unset(_tbb_compiler_subdir)
+unset(_tbbmalloc_proxy_ix)
+unset(_tbbmalloc_ix)
+unset(_tbb_lib_path)
+unset(_tbb_release_lib)
+unset(_tbb_debug_lib)
diff --git a/cmake/tbb/templates/TBBConfigForSource.cmake.in b/cmake/tbb/templates/TBBConfigForSource.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..e708a9b8f09f9b460ae5f1911deb3c11d0e5e7be
--- /dev/null
+++ b/cmake/tbb/templates/TBBConfigForSource.cmake.in
@@ -0,0 +1,82 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+# TBB_FOUND should not be set explicitly. It is defined automatically by CMake.
+# Handling of TBB_VERSION is in TBBConfigVersion.cmake.
+
+if (NOT TBB_FIND_COMPONENTS)
+    set(TBB_FIND_COMPONENTS "@TBB_DEFAULT_COMPONENTS@")
+    foreach (_tbb_component ${TBB_FIND_COMPONENTS})
+        set(TBB_FIND_REQUIRED_${_tbb_component} 1)
+    endforeach()
+endif()
+
+# Add components with internal dependencies: tbbmalloc_proxy -> tbbmalloc
+list(FIND TBB_FIND_COMPONENTS tbbmalloc_proxy _tbbmalloc_proxy_ix)
+if (NOT _tbbmalloc_proxy_ix EQUAL -1)
+    list(FIND TBB_FIND_COMPONENTS tbbmalloc _tbbmalloc_ix)
+    if (_tbbmalloc_ix EQUAL -1)
+        list(APPEND TBB_FIND_COMPONENTS tbbmalloc)
+        set(TBB_FIND_REQUIRED_tbbmalloc ${TBB_FIND_REQUIRED_tbbmalloc_proxy})
+    endif()
+endif()
+
+set(TBB_INTERFACE_VERSION @TBB_INTERFACE_VERSION@)
+
+get_filename_component(_tbb_root "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_tbb_root "${_tbb_root}" PATH)
+
+foreach (_tbb_component ${TBB_FIND_COMPONENTS})
+    set(_tbb_release_lib "@TBB_RELEASE_DIR@/@TBB_LIB_PREFIX@${_tbb_component}.@TBB_LIB_EXT@")
+    set(_tbb_debug_lib "@TBB_DEBUG_DIR@/@TBB_LIB_PREFIX@${_tbb_component}_debug.@TBB_LIB_EXT@")
+
+    if (EXISTS "${_tbb_release_lib}" OR EXISTS "${_tbb_debug_lib}")
+        add_library(TBB::${_tbb_component} SHARED IMPORTED)
+        set_target_properties(TBB::${_tbb_component} PROPERTIES
+                              INTERFACE_INCLUDE_DIRECTORIES "${_tbb_root}/include"@TBB_COMPILE_DEFINITIONS@)
+
+
+        if (EXISTS "${_tbb_release_lib}")
+            set_target_properties(TBB::${_tbb_component} PROPERTIES
+                                  IMPORTED_LOCATION_RELEASE "${_tbb_release_lib}"@TBB_IMPLIB_RELEASE@)
+            set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+        endif()
+
+        if (EXISTS "${_tbb_debug_lib}")
+            set_target_properties(TBB::${_tbb_component} PROPERTIES
+                                  IMPORTED_LOCATION_DEBUG "${_tbb_debug_lib}"@TBB_IMPLIB_DEBUG@)
+            set_property(TARGET TBB::${_tbb_component} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+        endif()
+
+        # Add internal dependencies for imported targets: TBB::tbbmalloc_proxy -> TBB::tbbmalloc
+        if (_tbb_component STREQUAL tbbmalloc_proxy)
+            set_target_properties(TBB::tbbmalloc_proxy PROPERTIES INTERFACE_LINK_LIBRARIES TBB::tbbmalloc)
+        endif()
+
+        list(APPEND TBB_IMPORTED_TARGETS TBB::${_tbb_component})
+        set(TBB_${_tbb_component}_FOUND 1)
+    elseif (TBB_FIND_REQUIRED AND TBB_FIND_REQUIRED_${_tbb_component})
+        message(FATAL_ERROR "Missed required Intel TBB component: ${_tbb_component}")
+    endif()
+endforeach()
+
+unset(_tbbmalloc_proxy_ix)
+unset(_tbbmalloc_ix)
+unset(_tbb_lib_path)
+unset(_tbb_release_lib)
+unset(_tbb_debug_lib)
diff --git a/cmake/tbb/templates/TBBConfigVersion.cmake.in b/cmake/tbb/templates/TBBConfigVersion.cmake.in
new file mode 100644
index 0000000000000000000000000000000000000000..69d16cf09cafe2dd20bf82e7b4e0f194db477a84
--- /dev/null
+++ b/cmake/tbb/templates/TBBConfigVersion.cmake.in
@@ -0,0 +1,28 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+#
+
+set(PACKAGE_VERSION @TBB_VERSION@)
+
+if ("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+    set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+        set(PACKAGE_VERSION_EXACT TRUE)
+    endif()
+endif()
diff --git a/src/threading/tbb.hpp b/src/threading/tbb.hpp
index 1156bf4be9de8752c41a831f1036c314475dc7a2..c7614bceca5abcd075746b71d4e0226159556a03 100644
--- a/src/threading/tbb.hpp
+++ b/src/threading/tbb.hpp
@@ -7,6 +7,7 @@
 #include <string>
 
 #include <tbb/tbb.h>
+#include <tbb/tbb_stddef.h>
 #include <tbb/compat/thread>
 #include <tbb/enumerable_thread_specific.h>
 
@@ -25,7 +26,7 @@ struct parallel_for {
 };
 
 inline std::string description() {
-    return "TBB";
+    return "TBBv" + std::to_string(tbb::TBB_runtime_interface_version());
 }
 
 struct timer {