diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 692acf9..db3b92f 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -931,6 +931,7 @@
   addCreatedFaceToForwarder(newFace);
   parameters.setFaceId(newFace->getId());
   parameters.setUri(newFace->getRemoteUri().toString());
+  parameters.setFacePersistency(newFace->getPersistency());
 
   sendResponse(requestName, 200, "Success", parameters.wireEncode());
 }
@@ -981,7 +982,7 @@
   try
     {
       factory->second->createFace(uri,
-                                  ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+                                  parameters.getFacePersistency(),
                                   bind(&FaceManager::onCreated,
                                        this, requestName, parameters, _1),
                                   bind(&FaceManager::onConnectFailed,
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index f9a2771..36e9e8a 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -1626,6 +1626,7 @@
   ControlParameters resultParameters;
   resultParameters.setUri("dummy://");
   resultParameters.setFaceId(FACEID_RESERVED_MAX + 1);
+  resultParameters.setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
 
   shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
 
diff --git a/tests/daemon/mgmt/face-manager/create-face.t.cpp b/tests/daemon/mgmt/face-manager/create-face.t.cpp
new file mode 100644
index 0000000..3a70619
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager/create-face.t.cpp
@@ -0,0 +1,449 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/face-manager.hpp"
+#include "mgmt/internal-face.hpp"
+#include "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <boost/property_tree/info_parser.hpp>
+
+namespace nfd {
+namespace tests {
+
+BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, BaseFixture)
+
+BOOST_AUTO_TEST_SUITE(CreateFace)
+
+class FaceManagerNode
+{
+public:
+  FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
+    : face(make_shared<InternalFace>())
+    , manager(forwarder.getFaceTable(), face, keyChain)
+  {
+    std::string basicConfig =
+      "face_system\n"
+      "{\n"
+      "  tcp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "  udp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "}\n"
+      "authorizations\n"
+      "{\n"
+      "  authorize\n"
+      "  {\n"
+      "    certfile any\n"
+      "    privileges\n"
+      "    {\n"
+      "      faces\n"
+      "    }\n"
+      "  }\n"
+      "}\n"
+      "\n";
+    std::istringstream input(basicConfig);
+    nfd::ConfigSection configSection;
+    boost::property_tree::read_info(input, configSection);
+
+    ConfigFile config;
+    manager.setConfigFile(config);
+    face->getValidator().setConfigFile(config);
+    config.parse(configSection, false, "dummy-config");
+  }
+
+  void
+  closeFaces()
+  {
+    std::vector<shared_ptr<Face>> facesToClose;
+    std::copy(forwarder.getFaceTable().begin(), forwarder.getFaceTable().end(),
+              std::back_inserter(facesToClose));
+    for (auto face : facesToClose) {
+      face->close();
+    }
+  }
+
+public:
+  Forwarder forwarder;
+  shared_ptr<InternalFace> face;
+  FaceManager manager;
+};
+
+class FaceManagerFixture : public UnitTestTimeFixture
+{
+public:
+  FaceManagerFixture()
+    : node1(keyChain, "16363")
+    , node2(keyChain, "26363")
+  {
+  }
+
+  ~FaceManagerFixture()
+  {
+    node1.closeFaces();
+    node2.closeFaces();
+    advanceClocks(time::milliseconds(1), 100);
+  }
+
+public:
+  ndn::KeyChain keyChain;
+  FaceManagerNode node1; // used to test FaceManager
+  FaceManagerNode node2; // acts as a remote endpoint
+};
+
+class TcpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class TcpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class TcpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class UdpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class UdpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class UdpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class Success
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(200)
+      .setText("Success");
+  }
+};
+
+template<int CODE>
+class Failure
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(CODE)
+      .setText("Error"); // error description should not be checked
+  }
+};
+
+namespace mpl = boost::mpl;
+
+// pairs of CreateCommand and Success status
+typedef mpl::vector<mpl::pair<TcpFaceOnDemand, Failure<500>>,
+                    mpl::pair<TcpFacePersistent, Success>,
+                    mpl::pair<TcpFacePermanent, Failure<500>>,
+                    mpl::pair<UdpFaceOnDemand, Failure<500>>,
+                    mpl::pair<UdpFacePersistent, Success>,
+                    mpl::pair<UdpFacePermanent, Success>> Faces;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerFixture)
+{
+  typedef typename T::first FaceType;
+  typedef typename T::second CreateResult;
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(FaceType().getParameters().wireEncode());
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  this->keyChain.sign(*command);
+
+  bool hasCallbackFired = false;
+  this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+      if (!command->getName().isPrefixOf(response.getName())) {
+        return;
+      }
+
+      ControlResponse actual(response.getContent().blockFromValue());
+      ControlResponse expected(CreateResult().getExpected());
+      BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
+      BOOST_MESSAGE(actual.getText());
+
+      if (actual.getBody().hasWire()) {
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+
+        BOOST_CHECK_EQUAL(expectedParams.getUri(), actualParams.getUri());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+      }
+      hasCallbackFired = true;
+    });
+
+  this->node1.face->sendInterest(*command);
+  this->advanceClocks(time::milliseconds(1), 10);
+
+  BOOST_CHECK(hasCallbackFired);
+}
+
+
+typedef mpl::vector<// mpl::pair<mpl::pair<TcpFacePersistent, TcpFacePermanent>, TcpFacePermanent>, // no need to check now
+                    // mpl::pair<mpl::pair<TcpFacePermanent, TcpFacePersistent>, TcpFacePermanent>, // no need to check now
+                    mpl::pair<mpl::pair<UdpFacePersistent, UdpFacePermanent>, UdpFacePermanent>,
+                    mpl::pair<mpl::pair<UdpFacePermanent, UdpFacePersistent>, UdpFacePermanent>> FaceTransitions;
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFace, T, FaceTransitions, FaceManagerFixture)
+{
+  typedef typename T::first::first FaceType1;
+  typedef typename T::first::second FaceType2;
+  typedef typename T::second FinalFaceType;
+
+  {
+    // create face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType1().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType2().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+        if (!command->getName().isPrefixOf(response.getName())) {
+          return;
+        }
+
+        ControlResponse actual(response.getContent().blockFromValue());
+        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
+
+        ControlParameters expectedParams(FinalFaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+
+// class TcpFace
+// {
+// public:
+//   ControlParameters
+//   getParameters()
+//   {
+//     return ControlParameters()
+//       .setUri("tcp4://127.0.0.1:16363")
+//       .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+//   }
+// };
+
+class UdpFace
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:16363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+
+// Note that the transitions from on-demand TcpFace are intentionally not tested.
+// On-demand TcpFace has a remote endpoint with a randomized port number.  Normal face
+// creation operations will not need to create a face toward a remote port not listened by
+// a channel.
+
+typedef mpl::vector<mpl::pair<UdpFace, UdpFacePersistent>,
+                    mpl::pair<UdpFace, UdpFacePermanent>> OnDemandFaceTransitions;
+
+// need a slightly different logic to test transitions from OnDemand state
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFaceOnDemand, T, OnDemandFaceTransitions, FaceManagerFixture)
+{
+  typedef typename T::first  OtherNodeFace;
+  typedef typename T::second FaceType;
+
+  {
+    // create on-demand face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(OtherNodeFace().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    ndn::util::signal::ScopedConnection connection =
+      this->node2.face->onReceiveData.connect([this, command] (const Data& response) {
+          if (!command->getName().isPrefixOf(response.getName())) {
+            return;
+          }
+
+          ControlResponse controlResponse(response.getContent().blockFromValue());
+          BOOST_REQUIRE_EQUAL(controlResponse.getText(), "Success");
+          BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 200);
+          uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
+          auto face = this->node2.forwarder.getFace(static_cast<FaceId>(faceId));
+
+          // to force creation of on-demand face
+          auto dummyInterest = make_shared<Interest>("/hello/world");
+          face->sendInterest(*dummyInterest);
+        });
+
+    this->node2.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  // make sure there is on-demand face
+  bool onDemandFaceFound = false;
+  FaceUri onDemandFaceUri(FaceType().getParameters().getUri());
+  for (auto face : this->node1.forwarder.getFaceTable()) {
+    if (face->getRemoteUri() == onDemandFaceUri) {
+      onDemandFaceFound = true;
+      break;
+    }
+  }
+  BOOST_REQUIRE(onDemandFaceFound);
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onReceiveData.connect([this, command, &hasCallbackFired] (const Data& response) {
+        if (!command->getName().isPrefixOf(response.getName())) {
+          return;
+        }
+
+        ControlResponse actual(response.getContent().blockFromValue());
+        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
+
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->sendInterest(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // CreateFace
+
+BOOST_AUTO_TEST_SUITE_END() // MgmtFaceManager
+
+} // tests
+} // nfd
