diff --git a/indra/newview/alviewermenu.cpp b/indra/newview/alviewermenu.cpp
index 23018b8f867e243035ff2cb7873fbca5c06a3fe8..9a1a8d3becb9b0864fbab08ae0187054346728e5 100644
--- a/indra/newview/alviewermenu.cpp
+++ b/indra/newview/alviewermenu.cpp
@@ -32,10 +32,13 @@
 #include "alcinematicmode.h"
 #include "alfloaterparticleeditor.h"
 #include "llagent.h"
+#include "llappviewer.h"
+#include "llavatarpropertiesprocessor.h"
 #include "llhudobject.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llselectmgr.h"
+#include "lltexturecache.h"
 #include "llviewercontrol.h"
 #include "llviewermenu.h"
 #include "llviewerobject.h"
@@ -321,6 +324,88 @@ namespace
 			LLFloaterReg::showInstance("generic_text", args);
 		}
 	}
+
+    void destroy_texture(const LLUUID& id)
+    {
+        if (id.isNull() || id == IMG_DEFAULT)
+            return;
+        LLViewerFetchedTexture* texture = LLViewerTextureManager::getFetchedTexture(id);
+        if (texture)
+            texture->clearFetchedResults();
+        LLAppViewer::getTextureCache()->removeFromCache(id);
+    }
+
+    void object_texture_refresh()
+	{
+        for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
+             iter != LLSelectMgr::getInstance()->getSelection()->valid_end();
+             ++iter)
+        {
+            LLSelectNode* node = *iter;
+            if (!node)
+                continue;
+            std::map<LLUUID, std::vector<U8>> faces_per_tex;
+            for (U8 i = 0; i < node->getObject()->getNumTEs(); ++i)
+            {
+                if (!node->isTESelected(i))
+                continue;
+                LLViewerTexture* img = node->getObject()->getTEImage(i);
+                faces_per_tex[img->getID()].push_back(i);
+
+                if (node->getObject()->getTE(i)->getMaterialParams().notNull())
+                {
+                LLViewerTexture* norm_img = node->getObject()->getTENormalMap(i);
+                faces_per_tex[norm_img->getID()].push_back(i);
+                LLViewerTexture* spec_img = node->getObject()->getTESpecularMap(i);
+                faces_per_tex[spec_img->getID()].push_back(i);
+                }
+            }
+
+            for (auto const& it : faces_per_tex)
+            {
+                destroy_texture(it.first);
+            }
+
+            if (node->getObject()->isSculpted() && !node->getObject()->isMesh())
+            {
+                const LLSculptParams* sculpt_params = node->getObject()->getSculptParams();
+                if (sculpt_params)
+                {
+                LLUUID                  sculptie = sculpt_params->getSculptTexture();
+                LLViewerFetchedTexture* tx       = LLViewerTextureManager::getFetchedTexture(sculptie);
+                if (tx)
+                {
+                        const LLViewerTexture::ll_volume_list_t* pVolumeList = tx->getVolumeList(LLRender::SCULPT_TEX);
+                        destroy_texture(sculptie);
+                        for (S32 idxVolume = 0; idxVolume < tx->getNumVolumes(LLRender::SCULPT_TEX); ++idxVolume)
+                        {
+                            LLVOVolume* pVolume = pVolumeList->at(idxVolume);
+                            if (pVolume)
+                                pVolume->notifyMeshLoaded();
+                        }
+                }
+                }
+            }
+        }
+	}
+
+    void avatar_texture_refresh()
+	{
+        LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+        if (!avatar) { return; }
+
+        for (U32 baked_idx = 0; baked_idx < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++baked_idx)
+        {
+            LLAvatarAppearanceDefines::ETextureIndex te_idx =
+                LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex(
+					static_cast<LLAvatarAppearanceDefines::EBakedTextureIndex>(baked_idx));
+            destroy_texture(avatar->getTE(te_idx)->getID());
+        }
+        LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(avatar->getID());
+
+        // *TODO: We want to refresh their attachments too!
+	}
+
 }
 
 ////////////////////////////////////////////////////////
@@ -338,6 +423,7 @@ void ALViewerMenu::initialize_menus()
 	commit.add("Avatar.CopyData",		[](LLUICtrl* ctrl, const LLSD& param) { avatar_copy_data(param); });
 	commit.add("Avatar.ManageEstate", [](LLUICtrl* ctrl, const LLSD& param) { manage_estate(param); });
 	commit.add("Avatar.TeleportTo", [](LLUICtrl* ctrl, const LLSD& param) { teleport_to(); });
+    commit.add("Avatar.RefreshTexture", [](LLUICtrl* ctrl, const LLSD& param) { avatar_texture_refresh(); });
 
 	commit.add("Advanced.DebugSimFeatures", [](LLUICtrl* ctrl, const LLSD& param) { spawn_debug_simfeatures(); });
 
@@ -346,6 +432,7 @@ void ALViewerMenu::initialize_menus()
 	commit.add("Object.AlchemyExplode", [](LLUICtrl* ctrl, const LLSD& param) { object_explode(); });
 	commit.add("Object.AlchemyDestroy", [](LLUICtrl* ctrl, const LLSD& param) { object_destroy(); });
 	commit.add("Object.AlchemyForceDelete", [](LLUICtrl* ctrl, const LLSD& param) { object_force_delete(); });
+    commit.add("Object.RefreshTexture", [](LLUICtrl* ctrl, const LLSD& param) { object_texture_refresh(); });
 
 	commit.add("Tools.UndeformSelf", [](LLUICtrl* ctrl, const LLSD& param) { avatar_undeform_self(); });
 
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 49c0f93d8ce6fff7274f3bc62f2229eb2c6fba3f..a8b4778ed52c01f46f6c94a49ebf70836ea60a2e 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -51,7 +51,13 @@
   <context_menu
    label="Appearance"
    name="Appearance">
-    <menu_item_call
+      <menu_item_call
+       label="Refresh Textures"
+       name="Refresh Textures">
+        <menu_item_call.on_click
+         function="Avatar.RefreshTexture" />
+	  </menu_item_call>
+	  <menu_item_call
       label="Reset Skeleton"
       name="Reset Skeleton">
       <menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 31f12d10970d86b98f6c997ef6088090febecc96..9fd37581ed7a75ffcb8be300998c3ae6e1ccfb31 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -307,6 +307,12 @@
      function="Tools.StopAllAnimations" />
   </menu_item_call>
   <menu_item_separator/>
+  <menu_item_call
+   label="Refresh Textures"
+   name="Refresh Textures">
+    <menu_item_call.on_click
+     function="Avatar.RefreshTexture" />
+  </menu_item_call>
   <menu_item_call label="Reset skeleton"
        layout="topleft"
        name="Reset Skeleton">
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index aaf5b784e3b6a83a6c452552f909af4c70a5bbaf..c5ff32ccf67e5b8a3a392541b2d17317d0916fd3 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -59,6 +59,12 @@
       <menu_item_call.on_click
        function="Avatar.ResetSkeleton" />
     </menu_item_call>
+    <menu_item_call
+     label="Refresh Textures"
+     name="Refresh Textures">
+      <menu_item_call.on_click
+       function="Avatar.RefreshTexture" />
+    </menu_item_call>
     <menu_item_call
      label="Reset Skeleton And Animations"
      name="Reset Skeleton And Animations">
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index c22d98a61c22df374f4d285d8df51404fc353dd2..d5421874c8eacf450447d77ea0101234cc147b35 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -277,6 +277,12 @@
          function="Tools.StopAllAnimations" />
   </menu_item_call>
   <menu_item_separator/>
+  <menu_item_call
+   label="Refresh Textures"
+   name="Refresh Textures">
+    <menu_item_call.on_click
+     function="Avatar.RefreshTexture" />
+  </menu_item_call>
   <menu_item_call label="Reset skeleton"
      layout="topleft"
      name="Reset Skeleton">
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index 1530a59caaff9311100166098b5ae39b61622b21..5d50f3e80ef216ef529a71631e9fa829ca66b8bb 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -162,6 +162,12 @@
     <menu_item_call.on_click
         function="Object.ZoomIn" />
   </menu_item_call>
+  <menu_item_call
+    label="Refresh Textures"
+    name="RefreshTextures">
+     <menu_item_call.on_click
+      function="Object.RefreshTexture" />
+  </menu_item_call>
   <menu_item_call
       label="Show in linksets"
       name="show_in_linksets">