diff --git a/CMake/External/External_TBB.cmake b/CMake/External/External_TBB.cmake
index 894925a95522ef6dc8965bd770b07d8d35cfde98..820408bb6b838963711e2d7b7812e5b71759f2d2 100644
--- a/CMake/External/External_TBB.cmake
+++ b/CMake/External/External_TBB.cmake
@@ -1,76 +1,3 @@
-
-# Set TBB_SOURCE_DIR and TBB_PREFIX
-imstk_define_external_dirs( TBB )
-
-# Version used to copy files & directories, and download archive from GitHub
-set(TBB_VER "2019_20191006oss")
-
-#-----------------------------------------------------------------------------
-# Set install commands
-#-----------------------------------------------------------------------------
-if(CMAKE_PROJECT_NAME STREQUAL "iMSTK")
-  set(TBB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
-
-  set(copy_tbb_config_command
-    ${CMAKE_COMMAND} -E copy
-      ${TBB_SOURCE_DIR}/tbb${TBB_VER}/cmake/TBBConfig.cmake
-      ${TBB_INSTALL_DIR}/cmake/TBBConfig.cmake
-    )
-
-  set(copy_tbb_headers_command
-    ${CMAKE_COMMAND} -E copy_directory
-      ${TBB_SOURCE_DIR}/tbb${TBB_VER}/include/tbb
-      ${TBB_INSTALL_DIR}/include/tbb
-    )
-
-  if(WIN32)
-    set(_subdir "intel64/vc14/")
-  elseif(APPLE)
-    set(_subdir "")
-  elseif(UNIX)
-    set(_subdir "intel64/gcc4.8/")
-  endif()
-
-  set(copy_tbb_libraries_command
-    ${CMAKE_COMMAND} -E copy_directory
-      ${TBB_SOURCE_DIR}/tbb${TBB_VER}/lib/${_subdir}
-      ${TBB_INSTALL_DIR}/lib/${_subdir}
-    )
-
-  set(TBB_INSTALL_COMMAND
-    INSTALL_COMMAND
-      COMMAND ${copy_tbb_config_command}
-      COMMAND ${copy_tbb_headers_command}
-      COMMAND ${copy_tbb_libraries_command}
-    )
-
-  if(WIN32)
-    set(copy_tbb_dll_to_bin_subdir_command
-      ${CMAKE_COMMAND} -E copy_directory
-        ${TBB_SOURCE_DIR}/tbb${TBB_VER}/bin/${_subdir}
-        ${TBB_INSTALL_DIR}/bin/${_subdir}
-      )
-    # Also copy dlls directly into bin folder to support
-    # calling "gtest_discover_tests" with working directory
-    # set to <CMAKE_INSTALL_PREFIX>/bin
-    set(copy_tbb_dll_to_bin_command
-      ${CMAKE_COMMAND} -E copy_directory
-        ${TBB_SOURCE_DIR}/tbb${TBB_VER}/bin/${_subdir}
-        ${TBB_INSTALL_DIR}/bin/
-      )
-    list(APPEND TBB_INSTALL_COMMAND
-      COMMAND ${copy_tbb_dll_to_bin_subdir_command}
-      COMMAND ${copy_tbb_dll_to_bin_command}
-      )
-  endif()
-
-else()
-  set(TBB_INSTALL_COMMAND
-    INSTALL_COMMAND
-      COMMAND ${SKIP_STEP_COMMAND}
-    )
-endif()
-
 #-----------------------------------------------------------------------------
 # Add External Project
 #-----------------------------------------------------------------------------
@@ -78,22 +5,14 @@ include(imstkAddExternalProject)
 
 # Download options
 if(NOT DEFINED iMSTK_TBB_GIT_SHA)
-  set(iMSTK_TBB_GIT_SHA "2019_U9")
+  # Version 2021.1.1
+  set(iMSTK_TBB_GIT_SHA "46fb877ef1618d9de9a9ba10cee107592b7cdb2d")
 endif()
 if(NOT DEFINED iMSTK_TBB_GIT_REPOSITORY)
-  if(WIN32)
-    set(tbb_file "tbb${TBB_VER}_win.zip")
-    set(tbb_md5 "a061a7c9821a374023201e8592860730")
-  elseif(APPLE)
-    set(tbb_file "tbb${TBB_VER}_mac.tgz")
-    set(tbb_md5 "43a0d6409317ee94f047622fd489a6c8")
-  else()
-    set(tbb_file "tbb${TBB_VER}_lin.tgz")
-    set(tbb_md5 "b5025847fa47040b4d2da8d6bdba0224")
-  endif()
   set(EXTERNAL_PROJECT_DOWNLOAD_OPTIONS
-    URL https://github.com/oneapi-src/oneTBB/releases/download/${iMSTK_TBB_GIT_SHA}/${tbb_file}
-    URL_HASH MD5=${tbb_md5}
+    # 2021.1
+    URL https://github.com/oneapi-src/oneTBB/archive/${iMSTK_TBB_GIT_SHA}.zip
+    URL_HASH MD5=1a0d5676ab568c8b9de57c7ecc082505
     )
 else()
   set(EXTERNAL_PROJECT_DOWNLOAD_OPTIONS
@@ -102,14 +21,8 @@ else()
     )
 endif()
 
-imstk_add_external_project(TBB
+imstk_add_external_project( TBB
   ${EXTERNAL_PROJECT_DOWNLOAD_OPTIONS}
-  DOWNLOAD_DIR ${TBB_PREFIX}
-  SOURCE_DIR ${TBB_SOURCE_DIR}
-  UPDATE_COMMAND ${SKIP_STEP_COMMAND}
-  CONFIGURE_COMMAND ${SKIP_STEP_COMMAND}
-  BUILD_COMMAND ${SKIP_STEP_COMMAND}
-  ${TBB_INSTALL_COMMAND}
-  #RELATIVE_INCLUDE_PATH ""
-  #VERBOSE
+  CMAKE_CACHE_ARGS
+    -DTBB_TEST:BOOL=OFF
 )
diff --git a/Source/Common/Parallel/imstkParallelFor.h b/Source/Common/Parallel/imstkParallelFor.h
index 77b26c93e89a844f9e0c90d21f62234830ab2015..89cf784782b3944e333d08dfad91f4366fdf636c 100644
--- a/Source/Common/Parallel/imstkParallelFor.h
+++ b/Source/Common/Parallel/imstkParallelFor.h
@@ -21,7 +21,12 @@
 
 #pragma once
 
+#include "imstkMacros.h"
+
+DISABLE_WARNING_PUSH
+    DISABLE_WARNING_PADDING
 #include <tbb/tbb.h>
+DISABLE_WARNING_POP
 
 namespace imstk
 {
diff --git a/Source/Common/Parallel/imstkParallelReduce.h b/Source/Common/Parallel/imstkParallelReduce.h
index fe661212a26b6e7689d37346acaaee0ff477fffb..e4e40dfa5dd05f34c2d4e818721d36ac7b9a9f8f 100644
--- a/Source/Common/Parallel/imstkParallelReduce.h
+++ b/Source/Common/Parallel/imstkParallelReduce.h
@@ -24,7 +24,10 @@
 #include "imstkMath.h"
 #include "imstkVecDataArray.h"
 
+DISABLE_WARNING_PUSH
+    DISABLE_WARNING_PADDING
 #include <tbb/tbb.h>
+DISABLE_WARNING_POP
 
 #undef min
 #undef max
diff --git a/Source/Common/Parallel/imstkThreadManager.cpp b/Source/Common/Parallel/imstkThreadManager.cpp
index 1aba79875405219af47be5feae8471f1a61c6681..d7f674f9bad71211b9c839ebf045043aad9c2915 100644
--- a/Source/Common/Parallel/imstkThreadManager.cpp
+++ b/Source/Common/Parallel/imstkThreadManager.cpp
@@ -47,7 +47,7 @@ ThreadManager::setThreadPoolSize(const size_t nThreads)
 void
 ThreadManager::setOptimalParallelism()
 {
-    setThreadPoolSize(static_cast<size_t>(tbb::task_scheduler_init::default_num_threads()));
+    setThreadPoolSize(static_cast<size_t>(tbb::info::default_concurrency()));
 }
 
 size_t
diff --git a/Source/Common/Parallel/imstkThreadManager.h b/Source/Common/Parallel/imstkThreadManager.h
index 263bef9a3f8768ed6925ddf373b9a80aded61de1..96774264c8811850ff07c10374226e8dec2dc11e 100644
--- a/Source/Common/Parallel/imstkThreadManager.h
+++ b/Source/Common/Parallel/imstkThreadManager.h
@@ -21,11 +21,13 @@
 
 #pragma once
 
-/// \todo Remove this in TBB 2019 Update 4: https://github.com/intel/tbb/blob/tbb_2019/CHANGES#L117
-#define TBB_PREVIEW_GLOBAL_CONTROL 1
+#include "imstkMacros.h"
 
+DISABLE_WARNING_PUSH
+    DISABLE_WARNING_PADDING
 #include <tbb/tbb.h>
 #include <tbb/global_control.h>
+DISABLE_WARNING_POP
 
 namespace imstk
 {
@@ -34,7 +36,6 @@ namespace ParallelUtils
 class ThreadManager
 {
 public:
-
     ///
     /// \brief Set system-wide thread pool size for parallel computation
     ///
diff --git a/Source/Common/TaskGraph/imstkTbbTaskGraphController.cpp b/Source/Common/TaskGraph/imstkTbbTaskGraphController.cpp
index 63fb4f6c0e2d391f2cc210ffd69686f6291c4533..821e592e91e0602f558d03f06d536e88d6a03992 100644
--- a/Source/Common/TaskGraph/imstkTbbTaskGraphController.cpp
+++ b/Source/Common/TaskGraph/imstkTbbTaskGraphController.cpp
@@ -20,86 +20,59 @@
 =========================================================================*/
 
 #include "imstkTbbTaskGraphController.h"
+#include "imstkMacros.h"
 #include "imstkTaskGraph.h"
 
-#include <tbb/tbb.h>
+DISABLE_WARNING_PUSH
+    DISABLE_WARNING_PADDING
+#include <tbb/flow_graph.h>
+DISABLE_WARNING_POP
+
+using namespace tbb::flow;
 
 namespace imstk
 {
-class NodeTbbTask : public tbb::task
+void
+TbbTaskGraphController::execute()
 {
-public:
-    NodeTbbTask(std::shared_ptr<TaskNode> node) : m_node(node) { }
-
-public:
-    task* execute() override
-    {
-        __TBB_ASSERT(ref_count() == 0, NULL);
+    using TbbContinueNode = continue_node<continue_msg>;
 
-        m_node->execute();
+    graph g;
 
-        for (size_t i = 0; i < successors.size(); i++)
-        {
-            if (successors[i]->decrement_ref_count() == 0)
-            {
-                spawn(*successors[i]);
-            }
-        }
-        return NULL;
-    }
+    broadcast_node<continue_msg> start(g);
 
-public:
-    std::shared_ptr<TaskNode> m_node = nullptr;
-    std::vector<NodeTbbTask*> successors;
-};
+    // Create a continue node for every TaskNode (except start)
+    std::unordered_map<std::shared_ptr<TaskNode>, TbbContinueNode> tbbNodes;
+    using NodeKeyValuePair = std::pair<std::shared_ptr<TaskNode>, TbbContinueNode>;
 
-void
-TbbTaskGraphController::execute()
-{
-    // Create a Task for every node
     const TaskNodeVector& nodes = m_graph->getNodes();
     if (nodes.size() == 0)
     {
         return;
     }
-
-    // Create a task for every node
-    std::unordered_map<std::shared_ptr<TaskNode>, NodeTbbTask*> tasks;
-    tasks.reserve(nodes.size());
-
+    tbbNodes.reserve(nodes.size());
     for (size_t i = 0; i < nodes.size(); i++)
     {
-        std::shared_ptr<TaskNode> node = nodes[i];
-        tasks[node] = new (tbb::task::allocate_root())NodeTbbTask(node);
+        if (m_graph->getSource() != nodes[i])
+        {
+            std::shared_ptr<TaskNode> node = nodes[i];
+            tbbNodes.insert(NodeKeyValuePair(node, TbbContinueNode(g,
+                [node](continue_msg) { node->execute(); })));
+        }
     }
-    // Increment successor reference counts
+
     const TaskNodeAdjList& adjList = m_graph->getAdjList();
-    // For every node in graph
-    for (size_t i = 0; i < nodes.size(); i++)
+    for (const auto& i : adjList)
     {
-        // If it contains outputs
-        if (adjList.count(nodes[i]) != 0)
+        TbbContinueNode& tbbNode1 = tbbNodes.at(i.first);
+        for (const auto& outputNode : i.second)
         {
-            // For every output
-            const TaskNodeSet& outputNodes = adjList.at(nodes[i]);
-            for (TaskNodeSet::const_iterator it = outputNodes.begin(); it != outputNodes.end(); it++)
-            {
-                // Lookup the task of the node
-                NodeTbbTask* successor = tasks[*it];
-                tasks[nodes[i]]->successors.push_back(successor);
-                successor->increment_ref_count();
-            }
+            TbbContinueNode& tbbNode2 = tbbNodes.at(outputNode);
+            make_edge(tbbNode1, tbbNode2);
         }
     }
 
-    NodeTbbTask* startTask = tasks[m_graph->getSource()];
-    NodeTbbTask* finalTask = tasks[m_graph->getSink()];
-
-    // Extra ref count on the final task
-    finalTask->increment_ref_count();
-    finalTask->spawn_and_wait_for_all(*startTask);
-
-    finalTask->execute(); // Execute final task explicitly
-    tbb::task::destroy(*finalTask);
+    start.try_put(continue_msg());
+    g.wait_for_all();
 }
 }
\ No newline at end of file
diff --git a/Source/Common/imstkModule.cpp b/Source/Common/imstkModule.cpp
index 62242c16a50a3aa188a6bceeb9eb6dc3c7f5a14a..1f3fadbcc5b05032658247da8cc75cd0fb234853 100644
--- a/Source/Common/imstkModule.cpp
+++ b/Source/Common/imstkModule.cpp
@@ -22,6 +22,8 @@
 #include "imstkModule.h"
 #include "imstkLogger.h"
 
+#include <thread>
+
 namespace imstk
 {
 void
diff --git a/Source/Common/imstkModule.h b/Source/Common/imstkModule.h
index db676fe44d75aa32f10583566d5df8f1cfd278eb..2d54283e3f4d5535f4d88f8eb5bcb4d4d5608422 100644
--- a/Source/Common/imstkModule.h
+++ b/Source/Common/imstkModule.h
@@ -24,9 +24,6 @@
 #include "imstkTimer.h"
 #include "imstkEventObject.h"
 
-#include <tbb/atomic.h>
-#include <thread>
-
 namespace imstk
 {
 ///
@@ -117,8 +114,8 @@ public:
     virtual void uninitModule() { }
 
 protected:
-    tbb::atomic<bool> m_init   = false;
-    tbb::atomic<bool> m_paused = false;
+    std::atomic<bool> m_init   = false;
+    std::atomic<bool> m_paused = false;
     double m_dt = 0.0;
     ExecutionType m_executionType = ExecutionType::PARALLEL; // Defaults to parallel, subclass and set
     bool   m_muteUpdateEvents     = false;                   // Avoid posting pre/post update, useful when running modules at extremely fast rates
diff --git a/Source/Common/imstkModuleDriver.h b/Source/Common/imstkModuleDriver.h
index 4725bcff5aad88603abec755b034f30c8309c9c5..d4fca772d8cffb8cece047ec08edbf178dc9e3a6 100644
--- a/Source/Common/imstkModuleDriver.h
+++ b/Source/Common/imstkModuleDriver.h
@@ -23,10 +23,6 @@
 
 #include "imstkEventObject.h"
 
-#include <memory>
-#include <tbb/atomic.h>
-#include <vector>
-
 namespace imstk
 {
 using ModuleDriverStatus = int;
@@ -72,6 +68,6 @@ public:
 protected:
     std::vector<std::shared_ptr<Module>> m_modules;
 
-    tbb::atomic<ModuleDriverStatus> simState = { ModuleDriverRunning };
+    std::atomic<ModuleDriverStatus> simState = { ModuleDriverRunning };
 };
 };
\ No newline at end of file
diff --git a/Source/SimulationManager/imstkSimulationManager.cpp b/Source/SimulationManager/imstkSimulationManager.cpp
index 90034f5bc3037865a1d49219a01816758af28e21..8459272e0a288e9b4af4ef251aaf7e809a1b1a78 100644
--- a/Source/SimulationManager/imstkSimulationManager.cpp
+++ b/Source/SimulationManager/imstkSimulationManager.cpp
@@ -20,33 +20,15 @@
 =========================================================================*/
 
 #include "imstkSimulationManager.h"
-#include "imstkViewer.h"
+#include "imstkMacros.h"
 #include "imstkTimer.h"
+#include "imstkViewer.h"
 
 #include <thread>
-#include <tbb/task.h>
-
-class FuncTask : public tbb::task
-{
-public:
-    FuncTask(std::shared_ptr<imstk::Module> module, std::function<void(std::shared_ptr<imstk::Module>)> func) :
-        m_func(func), m_module(module)
-    {
-    }
-
-    task* execute() override
-    {
-        __TBB_ASSERT(ref_count() == 0, NULL);
-
-        m_func(m_module);
-
-        return NULL;
-    }
-
-protected:
-    std::function<void(std::shared_ptr<imstk::Module>)> m_func;
-    std::shared_ptr<imstk::Module> m_module;
-};
+DISABLE_WARNING_PUSH
+    DISABLE_WARNING_PADDING
+#include <tbb/task_group.h>
+DISABLE_WARNING_POP
 
 namespace imstk
 {
@@ -76,18 +58,16 @@ SimulationManager::start()
     }
 
     // Start parallel modules
-    tbb::task_list           taskList;
+    tbb::task_group          tasks;
     std::vector<std::thread> threads(m_asyncModules.size());
     {
         if (m_threadType == ThreadingType::TBB)
         {
             for (auto module : m_asyncModules)
             {
-                FuncTask* moduleTask = new(tbb::task::allocate_root())FuncTask(module,
-                                                                               std::bind(&SimulationManager::runModuleParallel, this, std::placeholders::_1));
-                taskList.push_back(*moduleTask);
+                tasks.run([this, module]() { runModuleParallel(module); });
             }
-            tbb::task::spawn_root_and_wait(taskList);
+            tasks.wait();
         }
         else if (m_threadType == ThreadingType::STL)
         {