diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 4f45f95e8503e32e7f0ebd1315a4aa88ea935439..06ed632da863bb591f88777c335cd87baf5d75fe 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -669,6 +669,18 @@ F64 LLPluginClassMedia::getCPUUsage()
 	return result;
 }
 
+void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
+	message.setValue("file", file);
+	if(mPlugin->isBlocked())
+	{
+		// If the plugin sent a blocking pick-file request, the response should unblock it.
+		message.setValueBoolean("blocking_response", true);
+	}
+	sendMessage(message);
+}
+
 void LLPluginClassMedia::cut()
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index ee53f3a4da30bbb3215638b7a1bfc63e95ea10de..eaafbfe389ae1c6d0967a7aa94575786c16ae10a 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -156,6 +156,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void setLowPrioritySizeLimit(int size);
 	
 	F64 getCPUUsage();
+	
+	void sendPickFileResponse(const std::string &file);
 
 	// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
 	std::string getCursorName() const { return mCursorName; };
@@ -176,7 +178,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void	setLanguageCode(const std::string &language_code);
 	void	setPluginsEnabled(const bool enabled);
 	void	setJavascriptEnabled(const bool enabled);
-		
+	
 	///////////////////////////////////
 	// media browser class functions
 	bool pluginSupportsMediaBrowser(void);
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index 8a19e7530eb22969d96c07ffcb79b8ed7c5fe1ed..e60c85737fd017a2396c798252a5aeeb8b260d9b 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -55,6 +55,7 @@ class LLPluginClassMediaOwner
 		MEDIA_EVENT_CLICK_LINK_HREF,		// I'm not entirely sure what the semantics of these two are
 		MEDIA_EVENT_CLICK_LINK_NOFOLLOW,
 		MEDIA_EVENT_CLOSE_REQUEST,			// The plugin requested its window be closed (currently hooked up to javascript window.close in webkit)
+		MEDIA_EVENT_PICK_FILE_REQUEST,		// The plugin wants the user to pick a file
 		
 		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch 
 		MEDIA_EVENT_PLUGIN_FAILED			// The plugin died unexpectedly
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index de4409fba7382994edce4d5ae0988843c2527457..a7189cb610c624c3614d736f3bd5f098bd74d9d0 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -688,6 +688,26 @@ class MediaPluginWebKit :
 			
 		}
 	}
+	
+	std::string mPickedFile;
+	
+	std::string blockingPickFile(void)
+	{
+		mPickedFile.clear();
+		
+		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
+		message.setValueBoolean("blocking_request", true);
+		
+		// The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+		sendMessage(message);
+		
+		return mPickedFile;
+	}
+
+	void onPickFileResponse(const std::string &file)
+	{
+		mPickedFile = file;
+	}
 
 };
 
@@ -1045,10 +1065,14 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 				LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
 				checkEditState();
 			}
+			if(message_name == "pick_file_response")
+			{
+				onPickFileResponse(message_in.getValue("file"));
+			}
 			else
 			{
 //				std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
-			};
+			}
 		}
 		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
 		{
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 40ae9b06b785951af67c3c035c83fa14858b76cf..1de249a3c14531e58090e44ae8a0f1d73794d63a 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -956,6 +956,12 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
 		}
 		break;
+		
+		case MEDIA_EVENT_PICK_FILE_REQUEST:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
+		}
+		break;
 	};
 
 	// chain all events to any potential observers of this object.
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 2e3570a3afe700bf55d20300d1b8df61ef08e82d..012a4d29201ddf9ecc7f5d1458fe6509b081a134 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -51,6 +51,7 @@
 #include "llvoavatarself.h"
 #include "llviewerregion.h"
 #include "llwebsharing.h"	// For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
+#include "llfilepicker.h"
 
 #include "llevent.h"		// LLSimpleListener
 #include "llnotificationsutil.h"
@@ -2967,6 +2968,22 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 		}
 		break;
 
+		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
+		{
+			// Display a file picker
+			std::string response;
+			
+			LLFilePicker& picker = LLFilePicker::instance();
+			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
+			{
+				// The user didn't pick a file -- the empty response string will indicate this.
+			}
+			
+			response = picker.getFirstFile();
+			
+			plugin->sendPickFileResponse(response);
+		}
+		break;
 		
 		default:
 		break;
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 0cb1ad2f39d2d82aec29567750619892fdb42ea9..335776029ff11905bee3cc37cbb625b00df8b8d9 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -574,6 +574,12 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
 			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
 		}
 		break;
+		
+		case MEDIA_EVENT_PICK_FILE_REQUEST:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
+		}
+		break;
 	};
 }
 
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 89a514f376d695aa35f066945a5ebf196c1ba1c0..1d6ea8e2703a559ada944062a8f586526cc75181 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -2212,6 +2212,12 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
 		case MEDIA_EVENT_CLOSE_REQUEST:
 			std::cerr <<  "Media event:  MEDIA_EVENT_CLOSE_REQUEST" << std::endl;
 		break;
+		
+		case MEDIA_EVENT_PICK_FILE_REQUEST:
+			std::cerr <<  "Media event:  MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl;
+			// TODO: display an actual file picker
+			self->sendPickFileResponse("cake");
+		break;
 	}
 }