diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 6878e7b9d660b30c1c63bf896fa6c5816a037204..ca4a3935afd2623ceb4713a2a6114be1d33fdafe 100755
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -929,6 +929,32 @@ void LLLineEditor::removeChar()
 	}
 }
 
+// Remove a word (set of characters up to next space/punctuation) from the text
+void LLLineEditor::removeWord(bool prev)
+{
+	const U32 pos(getCursor());
+	if (prev ? pos > 0 : static_cast<S32>(pos) < getLength())
+	{
+		U32 new_pos(prev ? prevWordPos(pos) : nextWordPos(pos));
+		if (new_pos == pos) // Other character we don't jump over
+			new_pos = prev ? prevWordPos(new_pos-1) : nextWordPos(new_pos+1);
+
+		const U32 diff(labs(pos - new_pos));
+		if (prev)
+		{
+			mText.erase(new_pos, diff);
+			setCursor(new_pos);
+		}
+		else
+		{
+			mText.erase(pos, diff);
+		}
+	}
+	else
+	{
+		LLUI::reportBadKeystroke();
+	}
+}
 
 void LLLineEditor::addChar(const llwchar uni_char)
 {
@@ -1356,7 +1382,10 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
 			else
 			if( 0 < getCursor() )
 			{
-				removeChar();
+				if (mask == MASK_CONTROL)
+					removeWord(true);
+				else
+					removeChar();
 			}
 			else
 			{
@@ -1366,6 +1395,14 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
 		handled = TRUE;
 		break;
 
+	case KEY_DELETE:
+		if (!mReadOnly && mask == MASK_CONTROL)
+		{
+			removeWord(false);
+			handled = true;
+		}
+		break;
+
 	case KEY_PAGE_UP:
 	case KEY_HOME:
 		if (!mIgnoreArrowKeys)
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 40f931ecc1e9b0d08fefa7d8a85c1f9b1f7e1b5d..3ee05d4e6db71a3e0bd48efc9bb1c3db4af8a207 100755
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -279,6 +279,7 @@ private:
 	void                    pasteHelper(bool is_primary);
 
 	void			removeChar();
+	void			removeWord(bool prev);
 	void			addChar(const llwchar c);
 	void			setCursorAtLocalPos(S32 local_mouse_x);
 	S32				findPixelNearestPos(S32 cursor_offset = 0) const;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index c2985aa5c22679f343502231596f393e2953678a..f7b61ec423ae5a61151813ae947daf9eba4d0d35 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1090,6 +1090,33 @@ void LLTextEditor::removeChar()
 	}
 }
 
+// Remove a word (set of characters up to next space/punctuation) from the text
+void LLTextEditor::removeWord(bool prev)
+{
+	const U32 pos(mCursorPos);
+	if (prev ? pos > 0 : static_cast<S32>(pos) < getLength())
+	{
+		U32 new_pos(prev ? prevWordPos(pos) : nextWordPos(pos));
+		if (new_pos == pos) // Other character we don't jump over
+			new_pos = prev ? prevWordPos(new_pos-1) : nextWordPos(new_pos+1);
+
+		const U32 diff(labs(pos - new_pos));
+		if (prev)
+		{
+			remove(new_pos, diff, false);
+			setCursorPos(new_pos);
+		}
+		else
+		{
+			remove(pos, diff, false);
+		}
+	}
+	else
+	{
+		LLUI::reportBadKeystroke();
+	}
+}
+
 // Add a single character to the text
 S32 LLTextEditor::addChar(S32 pos, llwchar wc)
 {
@@ -1676,7 +1703,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
 		else
 		if( 0 < mCursorPos )
 		{
-			removeCharOrTab();
+			if (mask == MASK_CONTROL)
+				removeWord(true);
+			else
+				removeCharOrTab();
 		}
 		else
 		{
@@ -1684,6 +1714,16 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
 		}
 		break;
 
+	case KEY_DELETE:
+		if (getEnabled() && mask == MASK_CONTROL)
+		{
+			removeWord(false);
+		}
+		else
+		{
+			handled = false;
+		}
+		break;
 
 	case KEY_RETURN:
 		if (mask == MASK_NONE)
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index de5195e4f57032ebbe5589a5996796d83b4e035a..5378e3ad31acb13592d961fdef731875cd189d1e 100755
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -246,6 +246,7 @@ protected:
 	S32				overwriteChar(S32 pos, llwchar wc);
 	void			removeChar();
 	S32 			removeChar(S32 pos);
+	void			removeWord(bool prev);
 	S32				insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment);
 	S32				remove(S32 pos, S32 length, bool group_with_next_op);