diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index 32f16f73d2ad369dcd880b8f197f6dc446c0d331..ed924d1eb1c59b5b9d74f7ff865e8b8554435131 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -776,4 +776,11 @@ HMACkey = mySuperSecretValue
 ; field of the Solr index.
 driver = Default
 ; Should we display hierarchy trees? (default = false)
-;showTree = true
\ No newline at end of file
+;showTree = true
+; "Search within trees" can be disabled here if set to "false" (default = true)
+search = true
+; You can limit the number of search results highlighted when searching the tree;
+; a limit is recommended if you have large trees, as otherwise large numbers of
+; results can cause performance problems.  If treeSearchLimit is -1 or not set,
+; results will be unlimited.
+treeSearchLimit = 100
\ No newline at end of file
diff --git a/languages/en-gb.ini b/languages/en-gb.ini
index eabcbe868fdf19c033c35f6c1e12f4f7518157f2..56bf29e89ed69d6376b72ae4998b491036751b0f 100644
--- a/languages/en-gb.ini
+++ b/languages/en-gb.ini
@@ -716,6 +716,7 @@ too_many_new_items = "There are too many new items to display in a single list.
 too_many_reserves = "There are too many course reserves to display in a single list. Try limiting your search."
 top_facet_additional_prefix  = "Additional "
 top_facet_suffix             = "... within your search."
+tree_search_limit_reached_html = "Your search returned too many results to display in the tree. Showing only the first <b>%%limit%%</b> items. For a full search click <a id="fullSearchLink" href="%%url%%" target="_blank">here.</a>"
 upgrade_description = "If you are upgrading a previous VuFind version, you can load your old settings with this tool."
 view already selected = "view already selected"
 vudl_tab_docs = "Docs"
diff --git a/languages/en.ini b/languages/en.ini
index 8a1d5e043c0f12808c360b677c11063377b7b14b..7df08689af3f68219aadac11fc7109bf6355d8cb 100644
--- a/languages/en.ini
+++ b/languages/en.ini
@@ -716,6 +716,7 @@ too_many_new_items = "There are too many new items to display in a single list.
 too_many_reserves = "There are too many course reserves to display in a single list.  Try limiting your search."
 top_facet_additional_prefix  = "Additional "
 top_facet_suffix             = "... within your search."
+tree_search_limit_reached_html = "Your search returned too many results to display in the tree. Showing only the first <b>%%limit%%</b> items. For a full search click <a id="fullSearchLink" href="%%url%%" target="_blank">here.</a>"
 upgrade_description = "If you are upgrading a previous VuFind version, you can load your old settings with this tool."
 view already selected = "view already selected"
 vudl_tab_docs = "Docs"
diff --git a/module/VuFind/src/VuFind/Controller/HierarchyController.php b/module/VuFind/src/VuFind/Controller/HierarchyController.php
index 44e4c24d9b93dd35b62297c0b41c73c0994072fc..5b60453f1573476f3a1e98a3ef83a61f24feeb1c 100644
--- a/module/VuFind/src/VuFind/Controller/HierarchyController.php
+++ b/module/VuFind/src/VuFind/Controller/HierarchyController.php
@@ -45,7 +45,7 @@ class HierarchyController extends AbstractBase
      *
      * @return \Zend\Http\Response
      */
-    public function output($xml)
+    protected function output($xml)
     {
         $response = $this->getResponse();
         $headers = $response->getHeaders();
@@ -54,6 +54,59 @@ class HierarchyController extends AbstractBase
         return $response;
     }
 
+    /**
+     * Output JSON
+     *
+     * @param string $json A JSON string
+     *
+     * @return \Zend\Http\Response
+     */
+    protected function outputJSON($json)
+    {
+        $response = $this->getResponse();
+        $headers = $response->getHeaders();
+        $headers->addHeaderLine('Content-type', 'application/json');
+        $response->setContent($json);
+        return $response;
+    }
+
+    /**
+     * Search the tree and echo a json result of items that
+     * matched the keywords.
+     *
+     * @return void
+     * @access public
+     */
+    public function searchtreeAction()
+    {
+        $config = \VuFind\Config\Reader::getConfig();
+        $limit = isset($config->Hierarchy->treeSearchLimit)
+            ? $config->Hierarchy->treeSearchLimit : -1;
+        $resultIDs = array();
+        $hierarchyID = $this->params()->fromQuery('hierarchyID');
+        $lookfor = $this->params()->fromQuery('lookfor', '');
+        $searchType = $this->params()->fromQuery('type', 'AllFields');
+
+        $results = $this->getSearchManager()->setSearchClassId('Solr')->getResults();
+        $results->getParams()->setBasicSearch($lookfor, $searchType);
+        $results->getParams()->addFilter('hierarchy_top_id:' . $hierarchyID);
+        $facets = $results->getFullFieldFacets(array('id'), false, $limit+1);
+
+        $callback = function ($data) {
+            return $data['value'];
+        };
+        $resultIDs = isset($facets['id']['data']['list'])
+            ? array_map($callback, $facets['id']['data']['list']) : array();
+
+        $limitReached = ($limit > 0 && count($resultIDs) > $limit);
+
+        $returnArray = array(
+            "limitReached" => $limitReached,
+            "results" => array_slice($resultIDs, 0, $limit)
+        );
+        return $this->outputJSON(json_encode($returnArray));
+    }
+
     /**
      * Gets a Hierarchy Tree
      *
diff --git a/module/VuFind/src/VuFind/RecordTab/HierarchyTree.php b/module/VuFind/src/VuFind/RecordTab/HierarchyTree.php
index 5eca4a815ce990f52f0d788c41646f93d25836ed..5ab1debb8eb02b4d3456d210e00ff94a8d4a1365 100644
--- a/module/VuFind/src/VuFind/RecordTab/HierarchyTree.php
+++ b/module/VuFind/src/VuFind/RecordTab/HierarchyTree.php
@@ -46,6 +46,26 @@ class HierarchyTree extends AbstractBase
      */
     protected $treeList = null;
 
+    /**
+     * Configuration
+     *
+     * @var \Zend\Config\Config
+     */
+    protected $config = null;
+
+    /**
+     * Get the VuFind configuration.
+     *
+     * @return \Zend\Config\Config
+     */
+    protected function getConfig()
+    {
+        if (null === $this->config) {
+            $this->config = ConfigReader::getConfig();
+        }
+        return $this->config;
+    }
+
     /**
      * Get the on-screen description for this tab.
      *
@@ -155,4 +175,27 @@ class HierarchyTree extends AbstractBase
         }
         return '';
     }
+
+    /**
+     * Is tree searching active?
+     *
+     * @return bool
+     */
+    public function searchActive()
+    {
+        $config = $this->getConfig();
+        return (!isset($config->Hierarchy->search) || $config->Hierarchy->search);
+    }
+
+    /**
+     * Get the tree search result limit.
+     *
+     * @return int
+     */
+    public function getSearchLimit()
+    {
+        $config = $this->getConfig();
+        return isset($config->Hierarchy->treeSearchLimit)
+            ? $config->Hierarchy->treeSearchLimit : -1;
+    }
 }
\ No newline at end of file
diff --git a/themes/blueprint/css/styles.css b/themes/blueprint/css/styles.css
index 8d57697478a5bfcca447a9c04226e252a2df1213..601dbb855e805240f07bf013f806454c3342b569 100644
--- a/themes/blueprint/css/styles.css
+++ b/themes/blueprint/css/styles.css
@@ -1751,6 +1751,50 @@ div#closeContextHelp:active {
     overflow-y: auto;
 }
 
+#treeSearch {
+    display:none;
+    float: right;
+    width: 100%;
+    border: 1px solid  #DCDCDC;
+}
+
+#treeSearch #treeSearchText{
+    display:block;
+    float:right;
+    margin: 1px 0px 0px 0px;
+}
+
+#treeSearch #search {
+    display:block;
+    float:right;
+    margin-bottom: 0px;
+}
+
+#treeSearch #treeSearchType {
+    display:block;
+    float:right;
+    margin:2px 4px 0px 4px;
+}
+
+#treeSearch #treeSearchNoResults {
+    display:none;
+    float:left;
+    color: #AF1B0A;
+    margin:3px 0px 0px 5px;
+}
+
+#treeSearch #treeSearchLoadingImg {
+    display:none;
+    float:right;
+    margin:3px 4px 4px 5px;
+}
+
+#treeSearchLimitReached {
+    display:none;
+    color: #AF1B0A;
+    margin:3px 0px 0px 5px;
+}
+
 #modalDialog #hierarchyTree {
     max-height: 100%;
     min-height: 100%;
diff --git a/themes/blueprint/images/loading.gif b/themes/blueprint/images/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..471c1a4f93f2cabf0b3a85c3ff8e0a8aadefc548
Binary files /dev/null and b/themes/blueprint/images/loading.gif differ
diff --git a/themes/blueprint/js/hierarchyTree_JSTree.js b/themes/blueprint/js/hierarchyTree_JSTree.js
index c5cf88e1d28e385028fa327a61a8f1913cec34cc..059d3de3e31edd1ebe0cbb24833c27cc5cb89495 100644
--- a/themes/blueprint/js/hierarchyTree_JSTree.js
+++ b/themes/blueprint/js/hierarchyTree_JSTree.js
@@ -1,6 +1,7 @@
 var hierarchyID;
-$(document).ready(function() {
-
+var baseTreeSearchFullURL;
+$(document).ready(function()
+{
     hierarchyID = $("#hierarchyTree").find(".hiddenHierarchyId")[0].value;
     var recordID = $("#hierarchyTree").find(".hiddenRecordId")[0].value;
     var scroller = hierarchySettings.lightboxMode ? '#modalDialog' : '#hierarchyTree';
@@ -9,7 +10,8 @@ $(document).ready(function() {
     if (!hierarchySettings.fullHierarchy) {
         // Set Up Partial Hierarchy View Toggle
         $('#hierarchyTree').parent().prepend('<a href="#" id="toggleTree" class="closed">' + vufindString.showTree + '</a>');
-        $('#toggleTree').click(function(e) {
+        $('#toggleTree').click(function(e)
+        {
             e.preventDefault();
             $(this).toggleClass("open");
             $(this).hasClass("open") ? scroll(scroller, "show") : scroll(scroller, "hide");
@@ -18,15 +20,18 @@ $(document).ready(function() {
     }
 
     $("#hierarchyTree")
-    .bind("loaded.jstree", function (event, data) {
+    .bind("loaded.jstree", function (event, data)
+    {
         var idList = $('#hierarchyTree .JSTreeID');
-        $(idList).each(function() {
+        $(idList).each(function()
+        {
             var id = $.trim($(this).text());
             $(this).before('<input type="hidden" class="jsTreeID '+context+ '" value="'+id+'" />');
             $(this).remove();
         });
 
-        $("#hierarchyTree a").click(function(e) {
+        $("#hierarchyTree a").click(function(e)
+        {
             e.preventDefault();
             if (context == "Record") {
                 window.location = $(this).attr("href");
@@ -60,7 +65,8 @@ $(document).ready(function() {
         "xml_data" : {
             "ajax" : {
                 "url" : path + '/Hierarchy/GetTree?' + $.param({'hierarchyID': hierarchyID, 'id': recordID, 'context': context, mode: "Tree"}),
-                success: function(data) {
+                success: function(data)
+                {
                     // Necessary as data is a string
                     var dataAsXML = $.parseXML(data);
                     if(dataAsXML) {
@@ -75,7 +81,8 @@ $(document).ready(function() {
                         showTreeError("Unable to Parse XML");
                     }
                 },
-                failure: function() {
+                failure: function()
+                {
                     showTreeError("Unable to Load Tree");
                 }
             },
@@ -85,16 +92,29 @@ $(document).ready(function() {
         "themes" : {
             "url": path + '/themes/blueprint/js/jsTree/themes/vufind/style.css'
         }
-    }).bind("open_node.jstree close_node.jstree", function (e, data) {
+    }).bind("open_node.jstree close_node.jstree", function (e, data)
+    {
         $(data.args[0]).find("li").show();
     });
+
+    $('#treeSearch').show();
+    $('#treeSearchText').bind('keypress', function(e)
+    {
+        var code = (e.keyCode ? e.keyCode : e.which);
+        if(code == 13) {
+            // Enter keycode should call the search code
+            doTreeSearch();
+        }
+    });
 });
 
-function showTreeError(msg) {
+function showTreeError(msg)
+{
     $("#hierarchyTreeHolder").html('<p class="error">' + msg + '</p>');
 }
 
-function scroll(scroller, mode) {
+function scroll(scroller, mode)
+{
     // Get the currently cicked item
     var jsTreeNode = $(".jstree-clicked").parent('li');
     // Toggle display of closed nodes
@@ -114,7 +134,8 @@ function scroll(scroller, mode) {
     }
 }
 
-function hideFullHierarchy(jsTreeNode) {
+function hideFullHierarchy(jsTreeNode)
+{
     // Hide all nodes
     $('#hierarchyTree li').hide();
     // Show the nodes on the current path
@@ -122,3 +143,77 @@ function hideFullHierarchy(jsTreeNode) {
     // Show the nodes below the current path
     $(jsTreeNode).find("li").show();
 }
+
+function changeNoResultLabel(display)
+{
+    display ? $("#treeSearchNoResults").show() : $("#treeSearchNoResults").hide();
+}
+
+function changeLimitReachedLabel(display)
+{
+    display ? $("#treeSearchLimitReached").show() : $("#treeSearchLimitReached").hide();
+}
+
+function doTreeSearch()
+{
+    var keyword = $("#treeSearchText").val();
+    if (keyword == ""){
+        changeNoResultLabel(true);
+        return;
+    }
+    var searchType = $("#treeSearchType").val();
+
+    $("#treeSearchLoadingImg").show();
+    $.getJSON(path + '/Hierarchy/SearchTree?' + $.param({'lookfor': keyword, 'hierarchyID': hierarchyID, 'type': searchType}), function(results)
+    {
+        if (results["limitReached"] == true) {
+            if(typeof(baseTreeSearchFullURL) == "undefined" || baseTreeSearchFullURL == null){
+                baseTreeSearchFullURL = $("#fullSearchLink").attr("href");
+            }
+            $("#fullSearchLink").attr("href", baseTreeSearchFullURL + "?lookfor="+ keyword + "&filter[]=hierarchy_top_id:\"" + hierarchyID  + "\"");
+            changeLimitReachedLabel(true);
+        } else {
+            changeLimitReachedLabel(false);
+        }
+
+        if (results["results"].length >= 1) {
+            $("#hierarchyTree .jstree-search").removeClass("jstree-search");
+            $("#hierarchyTree").jstree("close_all", hierarchyID);
+            changeNoResultLabel(false);
+        } else {
+            $("#hierarchyTree .jstree-search").removeClass("jstree-search");
+            changeNoResultLabel(true);
+        }
+
+        $.each(results["results"], function(key, val)
+        {
+            var jsTreeNode = $(".jsTreeID:input[value="+val+"]").parent();
+            if (jsTreeNode.hasClass("jstree-closed")) {
+                jsTreeNode.removeClass("jstree-closed").addClass("jstree-open");
+            }
+            jsTreeNode.show().children('a:first').addClass("jstree-search");
+            var parents = $(jsTreeNode).parents();
+            parents.each(function() {
+                if ($(this).hasClass("jstree-closed")) {
+                    $(this).removeClass("jstree-closed").addClass("jstree-open");
+                }
+                $(this).show();
+            });
+        });
+        $("#treeSearchLoadingImg").hide();
+    });
+}
+// Code for the search button
+$(function ()
+{
+    $("#treeSearch input").click(function ()
+    {
+        switch(this.id) {
+            case "search":
+                doTreeSearch();
+                break;
+            default:
+                break;
+        }
+    });
+});
\ No newline at end of file
diff --git a/themes/blueprint/templates/RecordTab/hierarchytree.phtml b/themes/blueprint/templates/RecordTab/hierarchytree.phtml
index a60ae1bfefcd97beb193a85786549f768558636d..9c19fda27b1b0be4b65325e72afc1477e67bbbd3 100644
--- a/themes/blueprint/templates/RecordTab/hierarchytree.phtml
+++ b/themes/blueprint/templates/RecordTab/hierarchytree.phtml
@@ -27,6 +27,19 @@
   <? endif; ?>
   <? if ($activeTree): ?>
     <div id="hierarchyTreeHolder">
+      <? if ($this->tab->searchActive()): ?>
+        <div id="treeSearch">
+          <span id="treeSearchNoResults"><?=$this->transEsc('nohit_heading')?></span>
+          <input id="search" type="button" value="search" />
+          <select id="treeSearchType" name="type">
+            <option value="AllFields"><?=$this->transEsc('All Fields')?></option>
+            <option value="Title"><?=$this->transEsc('Title')?></option>
+          </select>
+          <input id="treeSearchText" type="text" value="" />
+          <span id="treeSearchLoadingImg"><img src="<?=$this->imageLink('loading.gif')?>"/></span>
+        </div>
+        <div id="treeSearchLimitReached"><?=$this->translate('tree_search_limit_reached_html', array('%%url%%' => $this->url('search-results'), '%%limit%%' => $this->tab->getSearchLimit()))?></div>
+      <? endif; ?>
       <div id="hierarchyTree">
         <input type="hidden" value="<?=$this->escapeHtml($this->driver->getUniqueId())?>" class="hiddenRecordId" />
         <input type="hidden" value="<?=$this->escapeHtml($activeTree)?>" class="hiddenHierarchyId" />