diff --git a/tools/ndn-tlv-peek.cpp b/tools/ndn-tlv-peek.cpp
new file mode 100644
index 0000000..8ed429d
--- /dev/null
+++ b/tools/ndn-tlv-peek.cpp
@@ -0,0 +1,257 @@
+/* -*- 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/asio.hpp>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace ndntlvpeek {
+
+class NdnTlvPeek
+{
+public:
+  NdnTlvPeek(char* programName)
+    : m_programName(programName)
+    , m_mustBeFresh(false)
+    , m_isChildSelectorRightmost(false)
+    , m_minSuffixComponents(-1)
+    , m_maxSuffixComponents(-1)
+    , m_interestLifetime(-1)
+    , m_isPayloadOnlySet(false)
+    , m_timeout(-1)
+    , m_prefixName("")
+    , m_isDataReceived(false)
+    , m_ioService(new boost::asio::io_service)
+    , m_face(m_ioService)
+  {
+  }
+
+  void
+  usage()
+  {
+    std::cout << "\n Usage:\n " << m_programName << " "
+      "[-f] [-r] [-m min] [-M max] [-l lifetime] [-p] [-w timeout] ndn:/name\n"
+      "   Get one data item matching the name prefix and write it to stdout\n"
+      "   [-f]          - set MustBeFresh\n"
+      "   [-r]          - set ChildSelector to select rightmost child\n"
+      "   [-m min]      - set MinSuffixComponents\n"
+      "   [-M max]      - set MaxSuffixComponents\n"
+      "   [-l lifetime] - set InterestLifetime in milliseconds\n"
+      "   [-p]          - print payload only, not full packet\n"
+      "   [-w timeout]  - set Timeout in milliseconds\n"
+      "   [-h]          - print help and exit\n\n";
+    exit(1);
+  }
+
+  void
+  setMustBeFresh()
+  {
+    m_mustBeFresh = true;
+  }
+
+  void
+  setRightmostChildSelector()
+  {
+    m_isChildSelectorRightmost = true;
+  }
+
+  void
+  setMinSuffixComponents(int minSuffixComponents)
+  {
+    if (minSuffixComponents < 0)
+      usage();
+    m_minSuffixComponents = minSuffixComponents;
+  }
+
+  void
+  setMaxSuffixComponents(int maxSuffixComponents)
+  {
+    if (maxSuffixComponents < 0)
+      usage();
+    m_maxSuffixComponents = maxSuffixComponents;
+  }
+
+  void
+  setInterestLifetime(int interestLifetime)
+  {
+    if (interestLifetime < 0)
+      usage();
+    m_interestLifetime = interestLifetime;
+  }
+
+  void
+  setPayloadOnly()
+  {
+    m_isPayloadOnlySet = true;
+  }
+
+  void
+  setTimeout(int timeout)
+  {
+    if (timeout < 0)
+      usage();
+    m_timeout = timeout;
+  }
+
+  void
+  setPrefixName(char* prefixName)
+  {
+    m_prefixName = prefixName;
+    if (m_prefixName.length() == 0)
+      usage();
+  }
+
+  int
+  getDefaultInterestLifetime()
+  {
+    return 4000;
+  }
+
+  ndn::Interest
+  createInterestPacket()
+  {
+    ndn::Name interestName(m_prefixName);
+    ndn::Interest interestPacket(interestName);
+    if (m_mustBeFresh)
+      interestPacket.setMustBeFresh(true);
+    if (m_isChildSelectorRightmost)
+      interestPacket.setChildSelector(1);
+    if (m_minSuffixComponents >= 0)
+      interestPacket.setMinSuffixComponents(m_minSuffixComponents);
+    if (m_maxSuffixComponents >= 0)
+      interestPacket.setMaxSuffixComponents(m_maxSuffixComponents);
+    if (m_interestLifetime < 0)
+      interestPacket.setInterestLifetime(getDefaultInterestLifetime());
+    else
+      interestPacket.setInterestLifetime(m_interestLifetime);
+    return interestPacket;
+  }
+
+  void
+  onData(const ndn::Interest& interest, ndn::Data& data)
+  {
+    int returnValue;
+    m_isDataReceived = true;
+    if (m_isPayloadOnlySet)
+      {
+        ndn::Block block = data.getContent();
+        returnValue = write(1, block.value(), block.value_size());
+      }
+    else
+      {
+        ndn::Block block = data.wireEncode();
+        returnValue = write(1, block.wire(), block.size());
+      }
+  }
+
+  void
+  onTimeout(const ndn::Interest& interest)
+  {
+  }
+
+  void
+  run()
+  {
+    try
+      {
+        m_face.expressInterest(createInterestPacket(),
+                               ndn::func_lib::bind(&NdnTlvPeek::onData,
+                                                   this, _1, _2),
+                               ndn::func_lib::bind(&NdnTlvPeek::onTimeout,
+                                                   this, _1));
+        if (m_timeout < 0)
+          {
+            if (m_interestLifetime < 0)
+              m_face.processEvents(getDefaultInterestLifetime());
+            else
+              m_face.processEvents(m_interestLifetime);
+          }
+        else
+          m_face.processEvents(m_timeout);
+      }
+    catch (std::exception& e)
+      {
+        std::cerr << "ERROR: " << e.what() << "\n" << std::endl;
+        exit(1);
+      }
+  }
+
+  bool
+  isDataReceived() const
+  {
+    return m_isDataReceived;
+  }
+
+private:
+
+  std::string m_programName;
+  bool m_mustBeFresh;
+  bool m_isChildSelectorRightmost;
+  int m_minSuffixComponents;
+  int m_maxSuffixComponents;
+  int m_interestLifetime;
+  bool m_isPayloadOnlySet;
+  int m_timeout;
+  std::string m_prefixName;
+  bool m_isDataReceived;
+  ndn::ptr_lib::shared_ptr<boost::asio::io_service> m_ioService;
+  ndn::Face m_face;
+};
+
+}
+
+int
+main(int argc, char* argv[])
+{
+  int option;
+  ndntlvpeek::NdnTlvPeek ndnTlvPeek (argv[0]);
+  while ((option = getopt(argc, argv, "hfrm:M:l:pw:")) != -1)
+    {
+      switch (option) {
+        case 'h':
+          ndnTlvPeek.usage();
+          break;
+        case 'f':
+          ndnTlvPeek.setMustBeFresh();
+          break;
+        case 'r':
+          ndnTlvPeek.setRightmostChildSelector();
+          break;
+        case 'm':
+          ndnTlvPeek.setMinSuffixComponents(atoi(optarg));
+          break;
+        case 'M':
+          ndnTlvPeek.setMaxSuffixComponents(atoi(optarg));
+          break;
+        case 'l':
+          ndnTlvPeek.setInterestLifetime(atoi(optarg));
+          break;
+        case 'p':
+          ndnTlvPeek.setPayloadOnly();
+          break;
+        case 'w':
+          ndnTlvPeek.setTimeout(atoi(optarg));
+          break;
+        default:
+          ndnTlvPeek.usage();
+      }
+    }
+
+  argc -= optind;
+  argv += optind;
+
+  if (argv[0] == 0)
+    ndnTlvPeek.usage();
+
+  ndnTlvPeek.setPrefixName(argv[0]);
+  ndnTlvPeek.run();
+
+  if (ndnTlvPeek.isDataReceived())
+    return 0;
+  else
+    return 1;
+}
