diff --git a/llvm/include/llvm/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.h b/llvm/include/llvm/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.h
new file mode 100644
index 0000000000000000000000000000000000000000..dfbd09402d7006dd7e42968fef387908b1928afc
--- /dev/null
+++ b/llvm/include/llvm/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.h
@@ -0,0 +1,25 @@
+#ifndef __EXTRACT_HPVM_LEAF_NODE_FUNCTIONS_H__
+	#define __EXTRACT_HPVM_LEAF_NODE_FUNCTIONS_H__
+	
+	//===-------------------- ExtractHPVMLeafNodeFunctions.h ------------------===//
+	//
+	//                     The LLVM Compiler Infrastructure
+	//
+	// This file is distributed under the University of Illinois Open Source
+	// License. See LICENSE.TXT for details.
+	//
+	//===----------------------------------------------------------------------===//
+	
+	#include "llvm/IR/Module.h"
+	#include "llvm/BuildDFG/BuildDFG.h"
+	
+	namespace extracthpvmleaf {
+	
+	class ExtractHPVMLeafNodeFunctions {
+	public:
+	  void run(Module &M, builddfg::BuildDFG &DFG);
+	};
+	
+	} // end namespace extracthpvmleaf
+	
+	#endif
\ No newline at end of file
diff --git a/llvm/include/llvm/SupportVISC/DFGTreeTraversal.h b/llvm/include/llvm/SupportVISC/DFGTreeTraversal.h
new file mode 100644
index 0000000000000000000000000000000000000000..c031c112fec67f6632db32efd6342018de923edd
--- /dev/null
+++ b/llvm/include/llvm/SupportVISC/DFGTreeTraversal.h
@@ -0,0 +1,64 @@
+#ifndef __DFGTREETRAVERSAL_H__
+#define __DFGTREETRAVERSAL_H__
+	
+//=== DFGTreeTraversal.h - Header file for Tree Traversal of the HPVM DFG ====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+	
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Pass.h"
+#include "llvm/BuildDFG/BuildDFG.h"
+	
+using namespace llvm;
+using namespace builddfg;
+	
+namespace dfg2llvm {
+	
+  class DFGTreeTraversal : public DFNodeVisitor {
+	
+  protected:
+    //Member variables
+    Module &M;
+    BuildDFG &DFG;
+	
+    virtual void process(DFInternalNode* N) = 0;
+    virtual void process(DFLeafNode* N) = 0;
+	
+    virtual ~DFGTreeTraversal() {}
+	
+  public:
+    // Constructor
+  DFGTreeTraversal(Module &_M, BuildDFG &_DFG) : M(_M), DFG(_DFG) {}
+	
+    void visit(DFInternalNode* N) {
+      // May visit a nodemore than once, there is no marking it as visited
+      errs() << "Start: In Node (I) - " << N->getFuncPointer()->getName() << "\n";
+	
+      // Follows a bottom-up approach.
+      for (DFGraph::children_iterator i = N->getChildGraph()->begin(),
+	     e = N->getChildGraph()->end(); i != e; ++i) {
+	DFNode* child = *i;
+	child->applyDFNodeVisitor(*this);
+      }
+	
+      // Process this internal node now.
+      process(N);
+      errs() << "DONE: In Node (I) - " << N->getFuncPointer()->getName() << "\n";
+    }
+	
+    void visit(DFLeafNode* N) {
+      errs() << "Start: In Node (L) - " << N->getFuncPointer()->getName() << "\n";
+      process(N);
+      errs() << "DONE: In Node (L) - " << N->getFuncPointer()->getName() << "\n";
+    }
+  };
+	
+} // end namespace dfg2llvm
+	
+#endif
diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt
index 9dd826ef4371298bb880fad5de9094335fb86779..96179638c5033e52b30cd5365cf9c3cfe4c330e9 100644
--- a/llvm/lib/Transforms/CMakeLists.txt
+++ b/llvm/lib/Transforms/CMakeLists.txt
@@ -24,3 +24,5 @@ add_subdirectory(FuseHPVMTensorNodes)
 add_subdirectory(ReplaceIntrinsics)
 add_subdirectory(DFG2LLVM_X86_dsoc)
 add_subdirectory(InlineTensorCalls)
+add_subdirectory(ExtractHPVMLeafNodes)
+
diff --git a/llvm/lib/Transforms/ExtractHPVMLeafNodes/CMakeLists.txt b/llvm/lib/Transforms/ExtractHPVMLeafNodes/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6421b528d766db0efc16e083c70d1d9328fcba84
--- /dev/null
+++ b/llvm/lib/Transforms/ExtractHPVMLeafNodes/CMakeLists.txt
@@ -0,0 +1,13 @@
+if(WIN32 OR CYGWIN)
+  set(LLVM_LINK_COMPONENTS Core Support)
+endif()
+
+add_llvm_loadable_module( ExtractHPVMLeafNodes
+  ExtractHPVMLeafNodes.cpp
+
+  DEPENDS
+  intrinsics_gen
+  PLUGIN_TOOL
+  opt
+  )
+
diff --git a/llvm/lib/Transforms/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.cpp b/llvm/lib/Transforms/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cd7ead9f6cda5048d03d1b56b0684dcfba368c73
--- /dev/null
+++ b/llvm/lib/Transforms/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.cpp
@@ -0,0 +1,246 @@
+//===------------------- ExtractHPVMLeafNodeGenFunctions.cpp -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+//
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "ExtractHPVMLeafNodes"
+
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Pass.h"
+#include "llvm/SupportVISC/DFGTreeTraversal.h"
+#include "llvm/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#include "llvm/IR/IRPrintingPasses.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/FileSystem.h"
+
+using namespace llvm;
+using namespace builddfg;
+using namespace extracthpvmleaf;
+using namespace dfg2llvm;
+
+namespace {
+
+class PrintLeafNodes : public DFGTreeTraversal {
+  public:
+  virtual void process(DFInternalNode* N) override;
+  virtual void process(DFLeafNode* N) override;
+
+  // Constructor
+  PrintLeafNodes(Module &_M, BuildDFG &_DFG) : DFGTreeTraversal(_M, _DFG) {}
+
+};
+
+}
+
+void PrintLeafNodes::process(DFInternalNode* N) {
+  DEBUG(errs() << "Analysing Node: " << N->getFuncPointer()->getName() << "\n");
+  return; // nothing to do
+}
+
+void PrintLeafNodes::process(DFLeafNode* N) {
+  DEBUG(errs() << "Analysing Node: " << N->getFuncPointer()->getName() << "\n");
+  if((N->isDummyNode())) {
+    DEBUG(errs() << "Skipping Dummy Node: " << N->getFuncPointer()->getName() << "\n");
+    return;
+  }
+
+  // Find function generated for node
+  Function *F = N->getGenFuncForTarget(visc::CPU_TARGET);
+  assert(F != NULL
+         && "This pass is invoked after code generation for x86 is completed.\nFound leaf node for which code generation has not happened!\n");
+  assert(N->hasX86GenFuncForTarget(visc::CPU_TARGET) &&
+         "The generated function from x86 pass is not an x86 function\n");
+
+  std::string module_name = std::string("./build/") + std::string(F->getName().str().c_str()) + std::string("_module.ll");
+  Twine tw(module_name);
+  // Create a new module for the node function
+  //Twine tw = Twine(F->getName()).concat(Twine("_module.ll"));
+  Module *m = new Module(tw.str(), F->getParent()->getContext());
+  // Create a new function for F. It will be written to a new module.
+  ValueToValueMapTy VMap;
+  Function *ClonedF = CloneFunction(F, VMap);
+  // Remove it from current module
+  ClonedF->removeFromParent();
+  // Insert it to the newly created module for it
+  m->getFunctionList().push_back(ClonedF);
+
+  std::vector<Instruction*> ItoRemove;
+
+  for (inst_iterator i = inst_begin(ClonedF), e = inst_end(ClonedF); i != e; ++i) {
+    Instruction *I = &(*i);
+    errs() << *I << "\n";
+
+    if (CallInst *CI = dyn_cast<CallInst>(I)) {
+      errs() << "Found call instruction\n";
+
+      Function *CalledF = CI->getCalledFunction();
+      StringRef CallName = CalledF->getName();
+      errs() << "CallName: " << CallName << "\n";
+
+//      if (CallName.startswith("llvm_visc")) { //TODO
+      if ((CallName.startswith("llvm_visc")) || (CallName.startswith("tensor"))) { //TODO
+//        errs() << "This is an HPVM runtime call. Include its declaration.\n";
+        errs() << "This is an HPVM runtime call or tensor. Include its declaration.\n";
+
+        FunctionType *CalledFType = CalledF->getFunctionType();
+
+        std::vector<Value*> Fargs;
+        for (unsigned argno = 0; argno < CI->getNumArgOperands(); argno++) {
+          Fargs.push_back(CI->getArgOperand(argno));
+        }
+        Function *FDecl = cast<Function>(m->getOrInsertFunction(CallName, CalledFType));
+        CallInst *NewCI = CallInst::Create(CalledFType, FDecl, Fargs, CallName, CI);
+        errs() << "NewCI: " << *NewCI << "\n";
+        CI->replaceAllUsesWith(NewCI);
+        ItoRemove.push_back(CI);
+      }
+    }
+  }
+
+  for (unsigned i = 0; i < ItoRemove.size() ; i++) {
+    ItoRemove[i]->eraseFromParent();
+  }
+
+  ItoRemove.clear();
+
+  // Print new module
+  legacy::PassManager Passes;
+
+  errs() << "Writing to File --- " << tw.str() << "\n";
+  std::error_code EC;
+  tool_output_file Out(tw.str(), EC, sys::fs::F_None);
+  if (EC) {
+    errs() << EC.message() << '\n';
+  }
+
+  Passes.add(createPrintModulePass(Out.os()));
+  Passes.run(*m);
+  // Declare success.
+  Out.keep();
+
+  // Any call that is to F, needs to call the new external function
+  // Edit initial module to do so
+  // This is the name with which the function is called now
+  StringRef FName = ClonedF->getName();
+  FunctionType *FType = F->getFunctionType();
+
+  // This is a node function, so it is only called through the dataflow graph
+  assert(F->hasOneUse() && "F is an HPVM node function\n");
+
+/*
+  errs() << "F uses: " << F->getNumUses()  << "\n" ;
+  for(Value::user_iterator ui = F->user_begin(),
+      ue = F->user_end(); ui!=ue; ++ui) {
+    errs() << "use : "<< **ui << "\n";
+  }
+*/
+
+  // Get the parent node's generated x86 function
+  DFInternalNode *ParentNode = N->getParent();
+  Function *PGenF = ParentNode->getGenFuncForTarget(visc::CPU_TARGET);
+  assert(PGenF != NULL
+         && "This pass is invoked after code generation for x86 is completed.\nFound node for which code generation has not happened!\n");
+  assert(ParentNode->hasX86GenFuncForTarget(visc::CPU_TARGET) &&
+         "The generated function from x86 pass is not an x86 function\n");
+
+  for (inst_iterator i = inst_begin(PGenF), e = inst_end(PGenF); i != e; ++i) {
+    Instruction *I = &(*i);
+    errs() << *I << "\n";
+
+    if (CallInst *CI = dyn_cast<CallInst>(I)) {
+      errs() << "Found call instruction\n";
+
+      StringRef CallName = CI->getCalledFunction()->getName();
+      errs() << "CallName: " << CallName << "\n";
+      errs() << "F->getName(): " << F->getName() << "\n";
+
+      if (CallName == F->getName()) {
+        // Found the call to the leaf node function we moved to the other module.
+        // Replace the call
+        std::vector<Value*> Fargs;
+        for (unsigned argno = 0; argno < CI->getNumArgOperands(); argno++) {
+          Fargs.push_back(CI->getArgOperand(argno));
+        }
+        Function *FDecl = cast<Function>(M.getOrInsertFunction(FName, FType));
+        CallInst *NewCI = CallInst::Create(FType, FDecl, Fargs, FName, CI);
+        errs() << "NewCI: " << *NewCI << "\n";
+        CI->replaceAllUsesWith(NewCI);
+        ItoRemove.push_back(CI);
+      }
+    }
+  }
+  
+  for (unsigned i = 0; i < ItoRemove.size() ; i++) {
+    ItoRemove[i]->eraseFromParent();
+  }
+
+  // Clean up
+  ClonedF->eraseFromParent();
+  delete m;
+
+  F->replaceAllUsesWith(UndefValue::get(F->getType()));
+  F->eraseFromParent();
+
+  return;
+}
+
+void ExtractHPVMLeafNodeFunctions::run(Module &M, BuildDFG &DFG) {
+
+  errs() << "\nEXTRACT HPVM LEAF NODE FUNCTIONS PASS\n";
+
+  std::vector<DFInternalNode*> Roots = DFG.getRoots();
+
+  // Visitor for Graph Traversal
+  PrintLeafNodes *LeafVisitor = new PrintLeafNodes(M, DFG);
+
+  // Iterate over all the DFGs
+  // Analyse the edges for parameters that are valid to be used in place
+  for (auto rootNode: Roots) {
+    LeafVisitor->visit(rootNode);
+  }
+
+  delete LeafVisitor;
+  return;
+}
+
+namespace {
+struct ExtractHPVMLeafNodeGenFunctionsWrapper : public ModulePass {
+  static char ID;
+  ExtractHPVMLeafNodeGenFunctionsWrapper() : ModulePass(ID) {}
+
+  bool runOnModule(Module &) override;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+} // end anonymous namespace
+
+void ExtractHPVMLeafNodeGenFunctionsWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<BuildDFG>();
+  AU.addPreserved<BuildDFG>();
+}
+
+bool ExtractHPVMLeafNodeGenFunctionsWrapper::runOnModule(Module &M) {
+  // Get the BuildDFG Analysis Results:
+  // - Dataflow graph
+  BuildDFG &DFG = getAnalysis<BuildDFG>();
+
+  ExtractHPVMLeafNodeFunctions ELNF;
+  ELNF.run(M, DFG);
+
+  return false;
+}
+
+char ExtractHPVMLeafNodeGenFunctionsWrapper::ID = 0;
+static RegisterPass<ExtractHPVMLeafNodeGenFunctionsWrapper> X(
+         "hpvm-extract-leaf-gen",
+         "Pass to extract leaf nodes to modules in HPVM",
+         false /* does not modify the CFG */,
+true /* transformation, not just analysis */);
diff --git a/llvm/lib/Transforms/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.exports b/llvm/lib/Transforms/ExtractHPVMLeafNodes/ExtractHPVMLeafNodes.exports
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/llvm/lib/Transforms/ExtractHPVMLeafNodes/LLVMBuild.txt b/llvm/lib/Transforms/ExtractHPVMLeafNodes/LLVMBuild.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9862f559e5d9e0ec6d47aa7eb3b8b811a79d8d79
--- /dev/null
+++ b/llvm/lib/Transforms/ExtractHPVMLeafNodes/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./lib/Transforms/DFG2LLVM_NVPTX/LLVMBuild.txt ------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = ExtractHPVMLeafNodes
+parent = Transforms
+