diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index dae4296a82ede79c202988180741751ed0bf5e9c..4456e0aa748d2df1807844619a5876ae35214a2d 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -58,7 +58,10 @@
 #include "llviewermessage.h"	// for handle_lure
 #include "llviewerregion.h"
 #include "llimfloater.h"
+#include "lltrans.h"
 
+// callback connection to auto-call when the IM floater initializes
+boost::signals2::connection gAdhocAutoCall;
 
 // static
 void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
@@ -205,6 +208,39 @@ void LLAvatarActions::startCall(const LLUUID& id)
 	make_ui_sound("UISndStartIM");
 }
 
+// static
+void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids)
+{
+	if (ids.size() == 0)
+	{
+		return;
+	}
+
+	// convert vector into LLDynamicArray for addSession
+	LLDynamicArray<LLUUID> id_array;
+	for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		id_array.push_back(*it);
+	}
+
+	// create the new ad hoc voice session
+	const std::string title = LLTrans::getString("conference-title");
+	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
+										   ids[0], id_array);
+	if (session_id == LLUUID::null)
+	{
+		return;
+	}
+
+	// always open IM window when connecting to voice
+	LLIMFloater::show(session_id);
+
+	// start the call once the floater has fully initialized
+	gAdhocAutoCall = LLIMModel::getInstance()->addSessionInitializedCallback(callbackAutoStartCall);
+
+	make_ui_sound("UISndStartIM");
+}
+
 // static
 bool LLAvatarActions::isCalling(const LLUUID &id)
 {
@@ -226,7 +262,8 @@ void LLAvatarActions::startConference(const std::vector<LLUUID>& ids)
 	{
 		id_array.push_back(*it);
 	}
-	LLUUID session_id = gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array);
+	const std::string title = LLTrans::getString("conference-title");
+	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
 	if (session_id != LLUUID::null)
 	{
 		LLIMFloater::show(session_id);
@@ -393,6 +430,17 @@ bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& re
     return false;
 }
 
+// static
+void LLAvatarActions::callbackAutoStartCall(const LLSD& data)
+{
+	// start the adhoc voice call now the IM panel has initialized
+	LLUUID session_id = data["session_id"].asUUID();
+	gIMMgr->startCall(session_id);
+
+	// and deschedule this callback as its work is done now
+	gAdhocAutoCall.disconnect();
+}
+
 // static
 void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
 {
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 0ec20ae3572477764a2ffed0c9e881682b9cbb83..66ea6880dbf22267c06beeaa6665ce9491401383 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -33,6 +33,13 @@
 #ifndef LL_LLAVATARACTIONS_H
 #define LL_LLAVATARACTIONS_H
 
+#include "lldarray.h"
+#include "llsd.h"
+#include "lluuid.h"
+
+#include <string>
+#include <vector>
+
 /**
  * Friend-related actions (add, remove, offer teleport, etc)
  */
@@ -71,6 +78,11 @@ class LLAvatarActions
 	 */
 	static void startCall(const LLUUID& id);
 
+	/**
+	 * Start an ad-hoc conference voice call with multiple users
+	 */
+	static void startAdhocCall(const std::vector<LLUUID>& ids);
+
 	/**
 	 * Start conference chat with the given avatars.
 	 */
@@ -117,6 +129,7 @@ class LLAvatarActions
 	static bool handleRemove(const LLSD& notification, const LLSD& response);
 	static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
 	static void callback_invite_to_group(LLUUID group_id, LLUUID id);
+	static void callbackAutoStartCall(const LLSD& data);
 
 	// Just request friendship, no dialog.
 	static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 476d312c69b75d923ed575b9c9d48276cd84f25b..14f94d5a8883bd3e488f08e5e8a120895a1dcc76 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -862,7 +862,17 @@ bool LLIMModel::sendStartSession(
 	return false;
 }
 
-
+// static
+void LLIMModel::sendSessionInitialized(const LLUUID &session_id)
+{
+	LLIMSession* session = getInstance()->findIMSession(session_id);
+	if (session)
+	{
+		LLSD arg;
+		arg["session_id"] = session_id;
+		getInstance()->mSessionInitializedSignal(arg);
+	}
+}
 
 //
 // Helper Functions
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index bd55bd2c30632ae9f5edb44f280698eaef7068e8..c566b111ca95cb8a061f3d37ba0f26cc7bb50c6a 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -102,6 +102,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	typedef boost::function<void(const LLSD&)> session_callback_t;
 	session_signal_t mNewMsgSignal;
 	session_signal_t mNoUnreadMsgsSignal;
+	session_signal_t mSessionInitializedSignal;
 	
 	/** 
 	 * Find an IM Session corresponding to session_id
@@ -116,6 +117,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 
 	boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); }
 	boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); }
+	boost::signals2::connection addSessionInitializedCallback(session_callback_t cb ) {	return mSessionInitializedSignal.connect(cb); }
 
 	/**
 	 * Create new session object in a model
@@ -189,6 +191,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
 						  const std::vector<LLUUID>& ids, EInstantMessage dialog);
 	static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing);
+	static void sendSessionInitialized(const LLUUID &session_id);
 	static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
 								const LLUUID& other_participant_id, EInstantMessage dialog);
 
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 350b78ee3daf3c5a70ce5e64546d65158f0863b2..5a0c1164de9a45c28cb6d100d2bb09363648665c 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -92,6 +92,14 @@ void LLPanelChatControlPanel::draw()
 		&& callback_enabled;
 	childSetEnabled("call_btn", enable_connect);
 
+	// send a signal when the floater is fully initialized
+	// this lets LLAvatarActions::startAdhocCall() start the call
+	if (enable_connect && !mInitialized)
+	{
+		LLIMModel::sendSessionInitialized(mSessionId);
+		mInitialized = true;
+	}
+
 	LLPanel::draw();
 }
 
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index a0d3420d231b66afd076dfd0f007acf10fd58230..923c5acbd217d53f2ba232d850510753d5af26a0 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -43,7 +43,9 @@ class LLParticipantList;
 class LLPanelChatControlPanel : public LLPanel
 {
 public:
-	LLPanelChatControlPanel() {};
+	LLPanelChatControlPanel() :
+		mSessionId(LLUUID()),
+		mInitialized(false) {};
 	~LLPanelChatControlPanel() {};
 
 	virtual BOOL postBuild();
@@ -59,6 +61,7 @@ class LLPanelChatControlPanel : public LLPanel
 
 private:
 	LLUUID mSessionId;
+	bool   mInitialized;
 };
 
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f6aded2d254ee8ff0e7d7470a187350a241c10ac..9ba94c8ca98eec7c08a3b6e5a4facdb90f27e3f4 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -755,7 +755,7 @@ void LLPanelPeople::updateButtons()
 	buttonSetEnabled("teleport_btn",		friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
 	buttonSetEnabled("view_profile_btn",	item_selected);
 	buttonSetEnabled("im_btn",				multiple_selected); // allow starting the friends conference for multiple selection
-	buttonSetEnabled("call_btn",			item_selected);
+	buttonSetEnabled("call_btn",			multiple_selected);
 	buttonSetEnabled("share_btn",			item_selected && false); // not implemented yet
 
 	bool none_group_selected = item_selected && selected_id.isNull();
@@ -1193,11 +1193,12 @@ void LLPanelPeople::onCallButtonClicked()
 	if (selected_uuids.size() == 1)
 	{
 		// initiate a P2P voice chat with the selected user
-		LLAvatarActions::startCall(getCurrentItemID());
+		LLAvatarActions::startCall(selected_uuids[0]);
 	}
 	else if (selected_uuids.size() > 1)
 	{
-		// *NOTE: ad-hoc voice chat not implemented yet
+		// initiate an ad-hoc voice chat with multiple users
+		LLAvatarActions::startAdhocCall(selected_uuids);
 	}
 }
 
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index c850dce141947d07008d4fc24c75be8d0e7fbd5b..b0a406a277c885e39f38dd5838115c6f90b2bb1c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2863,6 +2863,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   <string name="answering-im">
     Connecting...
   </string>
+  <string name="conference-title">
+    Friends Conference
+  </string>
   <string name="inventory_item_offered-im">
     Inventory item offered
   </string>