diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index e8eb555ddef473cb8c47e123ac4ca28729fa52cb..fb9022072a44c8d89cdba07e3465470936ff2c61 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -107,6 +107,7 @@ QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuic
 : QTextDocument(parent), outstanding(0)
 {
     setUndoRedoEnabled(false);
+    documentLayout()->registerHandler(QTextFormat::ImageObject, this);
 }
 
 QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
@@ -121,27 +122,8 @@ QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl
     QUrl url = context->resolvedUrl(name);
 
     if (type == QTextDocument::ImageResource) {
-        QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
-
-        if (iter == m_resources.end()) {
-            QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
-            iter = m_resources.insert(url, p);
-
-            if (p->isLoading()) {
-                p->connectFinished(this, SLOT(requestFinished()));
-                outstanding++;
-            }
-        }
-
-        QDeclarativePixmap *p = *iter;
-        if (p->isReady()) {
-            return p->image();
-        } else if (p->isError()) {
-            if (!errors.contains(url)) {
-                errors.insert(url);
-                qmlInfo(parent()) << p->error();
-            }
-        }
+        QDeclarativePixmap *p = loadPixmap(context, url);
+        return p->image();
     }
 
     return QTextDocument::loadResource(type,url); // The *resolved* URL
@@ -152,9 +134,7 @@ void QQuickTextDocumentWithImageResources::requestFinished()
     outstanding--;
     if (outstanding == 0) {
         markContentsDirty(0, characterCount());
-
-        if (QQuickText *item = qobject_cast<QQuickText *>(parent()))
-            QQuickTextPrivate::get(item)->updateLayout();
+        emit imagesLoaded();
     }
 }
 
@@ -165,6 +145,91 @@ void QQuickTextDocumentWithImageResources::clear()
     QTextDocument::clear();
 }
 
+
+QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
+        QTextDocument *, int, const QTextFormat &format)
+{
+    if (format.isImageFormat()) {
+        QTextImageFormat imageFormat = format.toImageFormat();
+
+        const bool hasWidth = imageFormat.hasProperty(QTextFormat::ImageWidth);
+        const int width = qRound(imageFormat.width());
+        const bool hasHeight = imageFormat.hasProperty(QTextFormat::ImageHeight);
+        const int height = qRound(imageFormat.height());
+
+        QSizeF size(width, height);
+        if (!hasWidth || !hasHeight) {
+            QDeclarativeContext *context = qmlContext(parent());
+            QUrl url = context->resolvedUrl(QUrl(imageFormat.name()));
+
+            QDeclarativePixmap *p = loadPixmap(context, url);
+            if (!p->isReady()) {
+                if (!hasWidth)
+                    size.setWidth(16);
+                if (!hasHeight)
+                    size.setHeight(16);
+                return size;
+            }
+            QSize implicitSize = p->implicitSize();
+
+            if (!hasWidth) {
+                if (!hasHeight)
+                    size.setWidth(implicitSize.width());
+                else
+                    size.setWidth(qRound(height * (implicitSize.width() / (qreal) implicitSize.height())));
+            }
+            if (!hasHeight) {
+                if (!hasWidth)
+                    size.setHeight(implicitSize.height());
+                else
+                    size.setHeight(qRound(width * (implicitSize.height() / (qreal) implicitSize.width())));
+            }
+        }
+        return size;
+    }
+    return QSizeF();
+}
+
+void QQuickTextDocumentWithImageResources::drawObject(
+        QPainter *, const QRectF &, QTextDocument *, int, const QTextFormat &)
+{
+}
+
+QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
+{
+    QDeclarativeContext *context = qmlContext(parent());
+    QUrl url = context->resolvedUrl(QUrl(format.name()));
+
+    QDeclarativePixmap *p = loadPixmap(context, url);
+    return p->image();
+}
+
+QDeclarativePixmap *QQuickTextDocumentWithImageResources::loadPixmap(
+        QDeclarativeContext *context, const QUrl &url)
+{
+
+    QHash<QUrl, QDeclarativePixmap *>::Iterator iter = m_resources.find(url);
+
+    if (iter == m_resources.end()) {
+        QDeclarativePixmap *p = new QDeclarativePixmap(context->engine(), url);
+        iter = m_resources.insert(url, p);
+
+        if (p->isLoading()) {
+            p->connectFinished(this, SLOT(requestFinished()));
+            outstanding++;
+        }
+    }
+
+    QDeclarativePixmap *p = *iter;
+    if (p->isError()) {
+        if (!errors.contains(url)) {
+            errors.insert(url);
+            qmlInfo(parent()) << p->error();
+        }
+    }
+    return p;
+}
+
 void QQuickTextDocumentWithImageResources::clearResources()
 {
     foreach (QDeclarativePixmap *pixmap, m_resources)
@@ -206,6 +271,12 @@ qreal QQuickTextPrivate::getImplicitWidth() const
     return implicitWidth;
 }
 
+void QQuickText::q_imagesLoaded()
+{
+    Q_D(QQuickText);
+    d->updateLayout();
+}
+
 void QQuickTextPrivate::updateLayout()
 {
     Q_Q(QQuickText);
@@ -830,6 +901,7 @@ void QQuickTextPrivate::ensureDoc()
         Q_Q(QQuickText);
         doc = new QQuickTextDocumentWithImageResources(q);
         doc->setDocumentMargin(0);
+        FAST_CONNECT(doc, SIGNAL(imagesLoaded()), q, SLOT(q_imagesLoaded()));
     }
 }
 
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 2292ea5f4d0bc36af31b8ce12761036679a8d4b4..ad3895358c683f9d2fc9988abcd9f43485009fef 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -203,6 +203,9 @@ protected:
     virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
     virtual bool event(QEvent *);
 
+private Q_SLOTS:
+    void q_imagesLoaded();
+
 private:
     Q_DISABLE_COPY(QQuickText)
     Q_DECLARE_PRIVATE(QQuickText)
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index fe25a02759100b9fdc2da32f47aa8413651ebad0..cf95fc61538b7e9e7cb269883d8203bb984bf3de 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -58,6 +58,7 @@
 #include "qquickimplicitsizeitem_p_p.h"
 
 #include <QtDeclarative/qdeclarative.h>
+#include <QtGui/qabstracttextdocumentlayout.h>
 #include <QtGui/qtextlayout.h>
 
 QT_BEGIN_NAMESPACE
@@ -167,9 +168,10 @@ public:
 };
 
 class QDeclarativePixmap;
-class QQuickTextDocumentWithImageResources : public QTextDocument {
+class QQuickTextDocumentWithImageResources : public QTextDocument, public QTextObjectInterface
+{
     Q_OBJECT
-
+    Q_INTERFACES(QTextObjectInterface)
 public:
     QQuickTextDocumentWithImageResources(QQuickItem *parent);
     virtual ~QQuickTextDocumentWithImageResources();
@@ -181,9 +183,19 @@ public:
 
     void clear();
 
+    QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
+    void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
+
+    QImage image(const QTextImageFormat &format);
+
+Q_SIGNALS:
+    void imagesLoaded();
+
 protected:
     QVariant loadResource(int type, const QUrl &name);
 
+    QDeclarativePixmap *loadPixmap(QDeclarativeContext *context, const QUrl &name);
+
 private slots:
     void requestFinished();
 
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index f1dcadad6780c76e1fb8ff51f79f5c1127824103..0ecaf4cf05b64c6d40bd39e074d7e7b579323676 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -1773,6 +1773,7 @@ void QQuickTextEditPrivate::init()
 #endif
     FAST_CONNECT(document, SIGNAL(undoAvailable(bool)), q, SIGNAL(canUndoChanged()));
     FAST_CONNECT(document, SIGNAL(redoAvailable(bool)), q, SIGNAL(canRedoChanged()));
+    FAST_CONNECT(document, SIGNAL(imagesLoaded()), q, SLOT(updateSize()));
 
     document->setDefaultFont(font);
     document->setDocumentMargin(textMargin);
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 508f564c882145e4567fff836a5e8b42a2cf26d4..8cdd984735e8e3b1b20e7986e5d86e423f07451c 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -214,6 +214,10 @@ public:
     qreal paintedWidth() const;
     qreal paintedHeight() const;
 
+    QUrl baseUrl() const;
+    void setBaseUrl(const QUrl &url);
+    void resetBaseUrl();
+
     Q_INVOKABLE QRectF positionToRectangle(int) const;
     Q_INVOKABLE int positionAt(int x, int y) const;
     Q_INVOKABLE void moveCursorSelection(int pos);
@@ -283,9 +287,9 @@ private Q_SLOTS:
     void updateDocument();
     void updateCursor();
     void q_updateAlignment();
+    void updateSize();
 
 private:
-    void updateSize();
     void updateTotalLines();
     void updateImageCache(const QRectF &rect = QRectF());
 
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index bf7edf5f03cc45b419679f895eae9f89ddf579b9..801bca0ff9e06847329a9135547177e8c4ccdc42 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -82,6 +82,9 @@ public:
     {
     }
 
+    static QQuickTextEditPrivate *get(QQuickTextEdit *item) {
+        return static_cast<QQuickTextEditPrivate *>(QObjectPrivate::get(item)); }
+
     void init();
 
     void updateDefaultTextOption();
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index dedc456aaaa32d10a3c2e3f51fa658c0f5dae6e6..804e83fcd2a9090a314436dec0ea4332d2a8c7af 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -56,6 +56,7 @@
 #include <qtexttable.h>
 #include <qtextlist.h>
 #include <private/qdeclarativestyledtext_p.h>
+#include <private/qquicktext_p_p.h>
 #include <private/qfont_p.h>
 #include <private/qfontengine_p.h>
 #include <private/qrawfont_p.h>
@@ -702,8 +703,15 @@ namespace {
 
             if (format.objectType() == QTextFormat::ImageObject) {
                 QTextImageFormat imageFormat = format.toImageFormat();
-                QTextImageHandler *imageHandler = static_cast<QTextImageHandler *>(handler);
-                image = imageHandler->image(textDocument, imageFormat);
+                if (QQuickTextDocumentWithImageResources *imageDoc = qobject_cast<QQuickTextDocumentWithImageResources *>(textDocument)) {
+                    image = imageDoc->image(imageFormat);
+
+                    if (image.isNull())
+                        return;
+                } else {
+                    QTextImageHandler *imageHandler = static_cast<QTextImageHandler *>(handler);
+                    image = imageHandler->image(textDocument, imageFormat);
+                }
             }
 
             if (image.isNull()) {
diff --git a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
index 0e8eab18be6b47d5661c55b7d7c66c85deb7f213..fa9549afc7133340dae7296991032ba7b0365008 100644
--- a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp
@@ -39,6 +39,7 @@
 **
 ****************************************************************************/
 #include <qtest.h>
+#include <QtTest/QSignalSpy>
 #include <QTextDocument>
 #include <QtDeclarative/qdeclarativeengine.h>
 #include <QtDeclarative/qdeclarativecomponent.h>
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml
new file mode 100644
index 0000000000000000000000000000000000000000..150f7bd89846d1b5aee436bb3cf79e49a44b559c
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocal.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http/exists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml
new file mode 100644
index 0000000000000000000000000000000000000000..067b6d72da16526df0d1a16bb9a17323eb6a893d
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesLocalError.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http/notexists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml
new file mode 100644
index 0000000000000000000000000000000000000000..a82388269202b24f59ee2652b84f75c013ab7a5e
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemote.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http://127.0.0.1:42332/exists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml
new file mode 100644
index 0000000000000000000000000000000000000000..c6172b68dc7d960ce802e7797affaf04da31aa5b
--- /dev/null
+++ b/tests/auto/qtquick2/qquicktextedit/data/embeddedImagesRemoteError.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+TextEdit {
+    textFormat: TextEdit.RichText
+    text: "<img src='http://127.0.0.1:42332/notexists.png'>"
+}
diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/exists.png b/tests/auto/qtquick2/qquicktextedit/data/http/exists.png
new file mode 100644
index 0000000000000000000000000000000000000000..399bd0b1d9d920e11f73922a112d5bbfabf7f01e
Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/http/exists.png differ
diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
index b35d955e2d73feb2c939623ca8473730b27baf56..272ec1992405a187a318baa69c97bdfc765e56d1 100644
--- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
@@ -51,6 +51,7 @@
 #include <QtGui/qguiapplication.h>
 #include <private/qquicktextedit_p.h>
 #include <private/qquicktextedit_p_p.h>
+#include <private/qquicktext_p_p.h>
 #include <QFontMetrics>
 #include <QtQuick/QQuickView>
 #include <QDir>
@@ -174,6 +175,9 @@ private slots:
     void undo_keypressevents_data();
     void undo_keypressevents();
 
+    void embeddedImages();
+    void embeddedImages_data();
+
     void emptytags_QTBUG_22058();
 
 private:
@@ -3654,6 +3658,48 @@ void tst_qquicktextedit::undo_keypressevents()
     QVERIFY(textEdit->text().isEmpty());
 }
 
+void tst_qquicktextedit::embeddedImages_data()
+{
+    QTest::addColumn<QUrl>("qmlfile");
+    QTest::addColumn<QString>("error");
+    QTest::newRow("local") << testFileUrl("embeddedImagesLocal.qml") << "";
+    QTest::newRow("local-error") << testFileUrl("embeddedImagesLocalError.qml")
+        << testFileUrl("embeddedImagesLocalError.qml").toString()+":3:1: QML TextEdit: Cannot open: " + testFileUrl("http/notexists.png").toString();
+    QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << "";
+    QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml")
+        << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML TextEdit: Error downloading http://127.0.0.1:42332/notexists.png - server replied: Not found";
+}
+
+void tst_qquicktextedit::embeddedImages()
+{
+    QFETCH(QUrl, qmlfile);
+    QFETCH(QString, error);
+
+    TestHTTPServer server(42332);
+    server.serveDirectory(testFile("http"));
+
+    if (!error.isEmpty())
+        QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
+
+    QDeclarativeComponent textComponent(&engine, qmlfile);
+    QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
+
+    QVERIFY(textObject != 0);
+    QTRY_COMPARE(QQuickTextEditPrivate::get(textObject)->document->resourcesLoading(), 0);
+
+    QPixmap pm(testFile("http/exists.png"));
+    if (error.isEmpty()) {
+        QCOMPARE(textObject->width(), double(pm.width()));
+        QCOMPARE(textObject->height(), double(pm.height()));
+    } else {
+        QVERIFY(16 != pm.width()); // check test is effective
+        QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
+        QCOMPARE(textObject->height(), 16.0);
+    }
+
+    delete textObject;
+}
+
 void tst_qquicktextedit::emptytags_QTBUG_22058()
 {
     QQuickView canvas(testFileUrl("qtbug-22058.qml"));