diff --git a/tools/ndn-tlv-poke.cpp b/tools/ndn-tlv-poke.cpp
new file mode 100644
index 0000000..51a12d9
--- /dev/null
+++ b/tools/ndn-tlv-poke.cpp
@@ -0,0 +1,254 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2014 University of Arizona.
+ *
+ * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ */
+
+#include <boost/utility.hpp>
+ 
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
+namespace ndntlvpoke {
+
+class NdnTlvPoke : boost::noncopyable
+{
+
+public:
+
+  explicit
+  NdnTlvPoke(char* programName)
+    : m_programName(programName)
+    , m_isForceDataSet(false)
+    , m_isUseDigestSha256Set(false)
+    , m_isLastAsFinalBlockIdSet(false)
+    , m_freshnessPeriod(-1)
+    , m_timeout(-1)
+    , m_isDataSent(false)
+  {
+  }
+
+  void
+  usage()
+  {
+    std::cout << "\n Usage:\n " << m_programName << " "
+      "[-f] [-D] [-i identity] [-F] [-x freshness] [-w timeout] ndn:/name\n"
+      "   Reads payload from stdin and sends it to local NDN forwarder as a "
+      "single Data packet\n"
+      "   [-f]          - force, send Data without waiting for Interest\n"
+      "   [-D]          - use DigestSha256 signing method instead of "
+      "SignatureSha256WithRsa\n"
+      "   [-i identity] - set identity to be used for signing\n"
+      "   [-F]          - set FinalBlockId to the last component of Name\n"
+      "   [-x]          - set FreshnessPeriod in milliseconds\n"
+      "   [-w timeout]  - set Timeout in milliseconds\n"
+      "   [-h]          - print help and exit\n\n";
+    exit(1);
+  }
+
+  void
+  setForceData()
+  {
+    m_isForceDataSet = true;
+  }
+
+  void
+  setUseDigestSha256()
+  {
+    m_isUseDigestSha256Set = true;
+  }
+
+  void
+  setIdentityName(char* identityName)
+  {
+    m_identityName = ndn::make_shared<ndn::Name>(identityName);
+  }
+
+  void
+  setLastAsFinalBlockId()
+  {
+    m_isLastAsFinalBlockIdSet = true;
+  }
+
+  void
+  setFreshnessPeriod(int freshnessPeriod)
+  {
+    if (freshnessPeriod < 0)
+      usage();
+    m_freshnessPeriod = freshnessPeriod;
+  }
+
+  void
+  setTimeout(int timeout)
+  {
+    if (timeout < 0)
+      usage();
+    m_timeout = timeout;
+  }
+
+  void
+  setPrefixName(char* prefixName)
+  {
+    m_prefixName = ndn::Name(prefixName);
+  }
+
+  ndn::Milliseconds
+  getDefaultTimeout()
+  {
+    return 10000;
+  }
+
+  ndn::Data
+  createDataPacket()
+  {
+    ndn::Data dataPacket(m_prefixName);
+    std::stringstream payloadStream;
+    payloadStream << std::cin.rdbuf();
+    std::string payload = payloadStream.str();
+    dataPacket.setContent(reinterpret_cast<const uint8_t*>(payload.c_str()), payload.length());
+    if (m_freshnessPeriod >= 0)
+      dataPacket.setFreshnessPeriod(m_freshnessPeriod);
+    if (m_isLastAsFinalBlockIdSet)
+      {
+        if (!m_prefixName.empty())
+          dataPacket.setFinalBlockId(m_prefixName.get(-1));
+        else
+          {
+            std::cerr << "Name Provided Has 0 Components" << std::endl;
+            exit(1);
+          }
+      }
+    if (m_isUseDigestSha256Set)
+      m_keyChain.signWithSha256(dataPacket);
+    else
+      {
+        if (!static_cast<bool>(m_identityName))
+          m_keyChain.sign(dataPacket);
+        else
+          m_keyChain.signByIdentity(dataPacket, *m_identityName);
+      }
+    return dataPacket;
+  }
+
+  void
+  onInterest(const ndn::Name& name,
+             const ndn::Interest& interest,
+             const ndn::Data& dataPacket)
+  {
+    m_face.put(dataPacket);
+    m_isDataSent = true;
+    m_face.shutdown();
+  }
+
+  void
+  onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
+  {
+    std::cerr << "Prefix Registration Failure." << std::endl;
+    std::cerr << "Reason = " << reason << std::endl;
+  }
+
+  void
+  run()
+  {
+    try
+      {
+        ndn::Data dataPacket = createDataPacket();
+        if (m_isForceDataSet)
+          {
+            m_face.put(dataPacket);
+            m_isDataSent = true;
+          }
+        else
+          {
+            m_face.setInterestFilter(m_prefixName,
+                                     ndn::func_lib::bind(&NdnTlvPoke::onInterest,
+                                                         this, _1, _2, dataPacket),
+                                     ndn::func_lib::bind(&NdnTlvPoke::onRegisterFailed,
+                                                         this, _1, _2));
+          }
+        if (m_timeout < 0)
+          m_face.processEvents(getDefaultTimeout());
+        else
+          m_face.processEvents(m_timeout);
+      }
+    catch (std::exception& e)
+      {
+        std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
+        exit(1);
+      }
+  }
+
+  bool
+  isDataSent() const
+  {
+    return m_isDataSent;
+  }
+
+private:
+
+  ndn::KeyChain m_keyChain;
+  std::string m_programName;
+  bool m_isForceDataSet;
+  bool m_isUseDigestSha256Set;
+  ndn::shared_ptr<ndn::Name> m_identityName;
+  bool m_isLastAsFinalBlockIdSet;
+  ndn::Milliseconds m_freshnessPeriod;
+  ndn::Milliseconds m_timeout;
+  ndn::Name m_prefixName;
+  bool m_isDataSent;
+  ndn::Face m_face;
+
+};
+
+}
+
+int
+main(int argc, char* argv[])
+{
+  int option;
+  ndntlvpoke::NdnTlvPoke ndnTlvPoke(argv[0]);
+  while ((option = getopt(argc, argv, "hfDi:Fx:w:")) != -1)
+    {
+      switch (option) {
+        case 'h':
+          ndnTlvPoke.usage();
+          break;
+        case 'f':
+          ndnTlvPoke.setForceData();
+          break;
+        case 'D':
+          ndnTlvPoke.setUseDigestSha256();
+          break;
+        case 'i':
+          ndnTlvPoke.setIdentityName(optarg);
+          break;
+        case 'F':
+          ndnTlvPoke.setLastAsFinalBlockId();
+          break;
+        case 'x':
+          ndnTlvPoke.setFreshnessPeriod(atoi(optarg));
+          break;
+        case 'w':
+          ndnTlvPoke.setTimeout(atoi(optarg));
+          break;
+        default:
+          ndnTlvPoke.usage();
+          break;
+      }
+    }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argv[0] == 0)
+    ndnTlvPoke.usage();
+
+  ndnTlvPoke.setPrefixName(argv[0]);
+  ndnTlvPoke.run();
+
+  if (ndnTlvPoke.isDataSent())
+    return 0;
+  else
+    return 1;
+}
