diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 2926e160d02d595d63cd3c78db8d601279196fe7..f70e9aa4888851959c711402c35e5e4c13dd61db 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -238,6 +238,8 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	void dumpSelectionInformation();
 
 	virtual S32	notify(const LLSD& info) ;
+
+	void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; }
 	
 	bool useLabelSuffix() { return mUseLabelSuffix; }
 	virtual void updateMenu();
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 8f4ca6c6337e47bde432c347c251079a8d657a97..5eecf1b9f53b1c8b24752d2137c0ea7dd9d2f5b2 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -392,6 +392,17 @@
         <key>Value</key>
         <string></string>
       </map>
+      <key>FavoritesFolder</key>
+      <map>
+        <key>Comment</key>
+        <string>User's chosen folder which will be shown in the Favorites tab (UUID)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>String</string>
+        <key>Value</key>
+        <string></string>
+      </map>
       <key>SnapshotBaseDir</key>
       <map>
         <key>Comment</key>
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d460aa145246c901e92f4e368362d5441a1358b5..d2149463989c7e4420db27ec02e20d0b988cc9a8 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -134,6 +134,35 @@ bool isMarketplaceSendAction(const std::string& action)
 	return ("send_to_marketplace" == action);
 }
 
+bool isPanelActive(const std::string& panel_name)
+{
+    LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
+    return (active_panel && (active_panel->getName() == panel_name));
+}
+
+bool isParentSystemFolder(const LLInventoryModel* model, const LLUUID& folder_id)
+{
+    if (!model || folder_id.isNull()) return false;
+
+    LLViewerInventoryCategory* cat = model->getCategory(folder_id);
+    if (cat)
+    {
+        if (cat->getPreferredType() == LLFolderType::FT_ROOT_INVENTORY)
+        {
+            return false;
+        }
+        if (LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
+        {
+            return true;
+        }
+        else
+        {
+            return isParentSystemFolder(model, cat->getParentUUID());
+        }
+    }
+    return false;
+}
+
 // Used by LLFolderBridge as callback for directory fetching recursion
 class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver
 {
@@ -884,8 +913,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 		disabled_items.push_back(std::string("Properties"));
 	}
 
-	LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
-	if (active_panel && (active_panel->getName() != "All Items"))
+	if (!isPanelActive("All Items"))
 	{
 		items.push_back(std::string("Show in Main Panel"));
 	}
@@ -976,7 +1004,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
 
 	items.push_back(std::string("Delete"));
 
-	if (!isItemRemovable())
+	if (!isItemRemovable() || isPanelActive("Favorite Items"))
 	{
 		disabled_items.push_back(std::string("Delete"));
 	}
@@ -3997,6 +4025,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 		disabled_items.push_back(std::string("New Clothes"));
 		disabled_items.push_back(std::string("New Body Parts"));
 		disabled_items.push_back(std::string("upload_def"));
+		disabled_items.push_back(std::string("Set Favorites folder"));
 	}
 	if (favorites == mUUID)
 	{
@@ -4024,6 +4053,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 		disabled_items.push_back(std::string("New Clothes"));
 		disabled_items.push_back(std::string("New Body Parts"));
 		disabled_items.push_back(std::string("upload_def"));
+		disabled_items.push_back(std::string("Set Favorites folder"));
     }
     if (marketplace_listings_id == mUUID)
     {
@@ -4032,14 +4062,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
         disabled_items.push_back(std::string("Cut"));
         disabled_items.push_back(std::string("Delete"));
     }
+
+	if (isPanelActive("Favorite Items"))
+	{
+		disabled_items.push_back(std::string("Delete"));
+	}
 	if(trash_id == mUUID)
 	{
-		bool is_recent_panel = false;
-		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
-		if (active_panel && (active_panel->getName() == "Recent Items"))
-		{
-			is_recent_panel = true;
-		}
+		bool is_recent_panel = isPanelActive("Recent Items");
 
 		// This is the trash.
 		items.push_back(std::string("Empty Trash"));
@@ -4087,6 +4117,11 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
                     items.push_back(std::string("New Clothes"));
                     items.push_back(std::string("New Body Parts"));
                     items.push_back(std::string("upload_def"));
+
+                    if (!LLFolderType::lookupIsProtectedType(getPreferredType()) && !isParentSystemFolder(model, mUUID))
+                    {
+                        items.push_back(std::string("Set Favorites folder"));
+                    }
                 }
 			}
 			getClipboardEntries(false, items, disabled_items, flags);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c49d61df31128c59ea8bd066868057e6fdc5a560..3cd38a5122fcc3a23d5c2415e5bec17f2427807b 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -542,6 +542,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType::
         cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder"));
         break;
     }
+    case LLFolderType::FT_FAVORITE:
+    {
+        cat_id = LLUUID(gSavedPerAccountSettings.getString("FavoritesFolder"));
+        break;
+    }
     default:
         break;
     }
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 6f461673ee0580752b9b88a9b35aae8e057e97f0..d7598bae91d6c905413c1e309764aaa10424bab0 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -169,6 +169,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
 	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 	mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2));
+	mCommitCallbackRegistrar.add("Inventory.SetFavoritesFolder", boost::bind(&LLInventoryPanel::setFavoritesFolder, this, _2));
 }
 
 LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
@@ -1344,6 +1345,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
     }
 }
 
+void LLInventoryPanel::setFavoritesFolder(const LLSD& userdata)
+{
+    gSavedPerAccountSettings.setString("FavoritesFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
+}
+
 void LLInventoryPanel::purgeSelectedItems()
 {
     if (!mFolderRoot.get()) return;
@@ -1729,6 +1735,95 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 	mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
 }
 
+static LLDefaultChildRegistry::Register<LLInventoryFavoriteItemsPanel> t_favorites_inventory_panel("favorites_inventory_panel");
+
+LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params)
+    : LLInventoryPanel(params)
+{
+    std::string ctrl_name = "FavoritesFolder";
+    if (gSavedPerAccountSettings.controlExists(ctrl_name))
+    {
+        LLPointer<LLControlVariable> cntrl_ptr = gSavedPerAccountSettings.getControl(ctrl_name);
+        if (cntrl_ptr.notNull())
+        {
+            mFolderChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder, this));
+        }
+    }
+}
+
+void LLInventoryFavoriteItemsPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
+{
+    if (mFolderRoot.get())
+    {
+        mFolderRoot.get()->setSelectCallback(cb);
+        mSelectionCallback = cb;
+    }
+}
+
+void LLInventoryFavoriteItemsPanel::initFromParams(const Params& p)
+{
+    Params fav_params(p);
+    fav_params.start_folder.id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+    LLInventoryPanel::initFromParams(fav_params);
+    updateFavoritesRootFolder();
+}
+
+void LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder()
+{
+    const LLUUID& folder_id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+
+    bool is_favorites_set = (folder_id != gInventory.findCategoryUUIDForTypeInRoot(LLFolderType::FT_FAVORITE, true, gInventory.getRootFolderID()));
+
+    if (!is_favorites_set || folder_id != getRootFolderID())
+    {
+        LLUUID root_id = folder_id;
+        if (mFolderRoot.get())
+        {
+            removeItemID(getRootFolderID());
+            mFolderRoot.get()->destroyView();
+        }
+
+        mCommitCallbackRegistrar.pushScope();
+        {
+            LLFolderView* folder_view = createFolderRoot(root_id);
+            mFolderRoot = folder_view->getHandle();
+
+            addItemID(root_id, mFolderRoot.get());
+
+
+            LLRect scroller_view_rect = getRect();
+            scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+            LLScrollContainer::Params scroller_params(mParams.scroll());
+            scroller_params.rect(scroller_view_rect);
+
+            if (mScroller)
+            {
+                removeChild(mScroller);
+                delete mScroller;
+                mScroller = NULL;
+            }
+            mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+            addChild(mScroller);
+            mScroller->addChild(mFolderRoot.get());
+            mFolderRoot.get()->setScrollContainer(mScroller);
+            mFolderRoot.get()->setFollowsAll();
+            mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
+
+            if (!mSelectionCallback.empty())
+            {
+                mFolderRoot.get()->setSelectCallback(mSelectionCallback);
+            }
+        }
+        mCommitCallbackRegistrar.popScope();
+        mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
+
+        if (is_favorites_set)
+        {
+            buildNewViews(folder_id);
+        }
+        mFolderRoot.get()->setShowEmptyMessage(!is_favorites_set);
+    }
+}
 namespace LLInitParam
 {
 	void TypeValues<LLFolderType::EType>::declareValues()
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 12001f5a2be5c16eece14e57fe6659d92137dc03..7d6adad9f3f574c67ce339e4711032abd4e04ed8 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -205,6 +205,7 @@ class LLInventoryPanel : public LLPanel
 	void doCreate(const LLSD& userdata);
 	bool beginIMSession();
 	void fileUploadLocation(const LLSD& userdata);
+	void setFavoritesFolder(const LLSD& userdata);
 	void purgeSelectedItems();
 	bool attachObject(const LLSD& userdata);
 	static void idle(void* user_data);
@@ -322,4 +323,24 @@ class LLInventoryPanel : public LLPanel
 	bool				mViewsInitialized; // Views have been generated
 };
 
+
+class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
+{
+public:
+    struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+    {};
+
+    void initFromParams(const Params& p);
+    bool isSelectionRemovable() { return false; }
+    void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
+
+protected:
+    LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params);
+    ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
+    void updateFavoritesRootFolder();
+
+    boost::signals2::connection mFolderChangedSignal;
+    boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
+    friend class LLUICtrlFactory;
+};
 #endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index f63e604927b75b9e9604b2b0ada2d934c5d0763a..0eb9ed0ed9f7257f5da23cd67ad2b79acbc12714 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -184,6 +184,16 @@ BOOL LLPanelMainInventory::postBuild()
 		worn_filter.markDefault();
 		mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2));
 	}
+
+	mFavoriteItemsPanel = getChild<LLInventoryFavoriteItemsPanel>("Favorite Items");
+	if (mFavoriteItemsPanel)
+	{
+		LLInventoryFilter& recent_filter = mFavoriteItemsPanel->getFilter();
+		recent_filter.setEmptyLookupMessage("InventoryFavoritItemsNotSelected");
+		recent_filter.markDefault();
+		mFavoriteItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mFavoriteItemsPanel, _1, _2));
+	}
+
 	mSearchTypeCombo  = getChild<LLComboBox>("search_type");
 	if(mSearchTypeCombo)
 	{
@@ -1390,7 +1400,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	}
 	if (command_name == "delete")
 	{
-		return getActivePanel()->isSelectionRemovable();
+		return getActivePanel()->isSelectionRemovable() && (getActivePanel() != mFavoriteItemsPanel);
 	}
 	if (command_name == "save_texture")
 	{
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 732a3b04e3dc92e56a5433c6f59248c33c35b9a3..bcb4f6737fcf3175c6d513c7a560e185fefcb25e 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -37,6 +37,7 @@
 class LLComboBox;
 class LLFolderViewItem;
 class LLInventoryPanel;
+class LLInventoryFavoriteItemsPanel;
 class LLSaveFolderState;
 class LLFilterEditor;
 class LLTabContainer;
@@ -136,6 +137,7 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 	LLHandle<LLFloater>			mFinderHandle;
 	LLInventoryPanel*			mActivePanel;
 	LLInventoryPanel*			mWornItemsPanel;
+	LLInventoryFavoriteItemsPanel* mFavoriteItemsPanel;
 	bool						mResortActivePanel;
 	LLSaveFolderState*			mSavedFolderState;
 	std::string					mFilterText;
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 3bdbbb04d78e5646bbc979c32f8f479d4157b003..52fcdc5b585a0fd47a3e0663f7fccc9855e3244b 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -358,6 +358,13 @@
          parameter="model" />
       </menu_item_call>
     </menu>
+      <menu_item_call
+       label="Use as Favorites folder"
+       layout="topleft"
+       name="Set Favorites folder">
+        <menu_item_call.on_click
+         function="Inventory.SetFavoritesFolder"/>
+      </menu_item_call>
     <menu
      label="Change Type"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index d77fbdec0ac28dd95c9c4ddfdaa169e3fb02ed17..2745b9d30216cc8d5a6647bb84222e59c60215a1 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -117,20 +117,32 @@
      name="Recent Items"
      show_item_link_overlays="true"
      width="290" />
-       <inventory_panel
-      name="Worn Items"
-      label="WORN"
-      show_empty_message="false"
-      follows="all"
-      layout="topleft"
-      width="290"
-      bg_opaque_color="DkGray2"
-      bg_alpha_color="DkGray2"
-      background_visible="true"
-      border="false"
-      bevel_style="none"
-      scroll.reserve_scroll_corner="false">
-  </inventory_panel>
+    <inventory_panel
+     name="Worn Items"
+     label="WORN"
+     show_empty_message="false"
+     follows="all"
+     layout="topleft"
+     width="290"
+     bg_opaque_color="DkGray2"
+     bg_alpha_color="DkGray2"
+     background_visible="true"
+     border="false"
+     bevel_style="none"
+     scroll.reserve_scroll_corner="false"/>
+    <favorites_inventory_panel
+     name="Favorite Items"
+     label="FAVORITES"
+     show_empty_message="false"
+     follows="all"
+     layout="topleft"
+     width="290"
+     bg_opaque_color="DkGray2"
+     bg_alpha_color="DkGray2"
+     background_visible="true"
+     border="false"
+     bevel_style="none"
+     scroll.reserve_scroll_corner="false"/>
   </tab_container>
   <layout_stack
    animate="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 0594e18c96728de023743c48aa6a57c5fbf23bd9..39627f722546c329f36e5f2716b10e217d52235b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2291,6 +2291,7 @@ For AI Character: Get the closest navigable point to the point provided.
 	<!-- inventory -->
 	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
 	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
+	<string name="InventoryFavoritItemsNotSelected">Click "Use as Favorites folder" on a folder of your choice. You can choose a different folder at any time. System folders cannot be used for Favorites.</string>
 	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
 	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
 	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>