diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp
index 4cb0e06eb62ccc482ddcfb65016fff6058123a75..bb01f531cd8d2ccc84bb4580cd102b1055366ed0 100644
--- a/src/core/print_view_manager_qt.cpp
+++ b/src/core/print_view_manager_qt.cpp
@@ -43,8 +43,8 @@
 #include "type_conversion.h"
 #include "web_engine_context.h"
 
-#include <QtGui/QPageLayout>
-#include <QtGui/QPageSize>
+#include <QtGui/qpagelayout.h>
+#include <QtGui/qpagesize.h>
 
 #include "base/values.h"
 #include "chrome/browser/printing/print_job_manager.h"
@@ -101,43 +101,58 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
         metafile.SaveTo(&file);
 }
 
-static void applyQPageLayoutSettingsToDictionary(const QPageLayout& pageLayout, base::DictionaryValue& print_settings)
+static base::DictionaryValue *createPrintSettings()
 {
+    base::DictionaryValue *printSettings = new base::DictionaryValue();
     // TO DO: Check if we can use the request ID from Qt here somehow.
     static int internalRequestId = 0;
 
-    print_settings.SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0);
-    print_settings.SetInteger(printing::kPreviewRequestID, internalRequestId);
+    printSettings->SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0);
+    printSettings->SetInteger(printing::kPreviewRequestID, internalRequestId);
+
+    // The following are standard settings that Chromium expects to be set.
+    printSettings->SetBoolean(printing::kSettingPrintToPDF, true);
+    printSettings->SetBoolean(printing::kSettingCloudPrintDialog, false);
+    printSettings->SetBoolean(printing::kSettingPrintWithPrivet, false);
+    printSettings->SetBoolean(printing::kSettingPrintWithExtension, false);
+
+    printSettings->SetBoolean(printing::kSettingGenerateDraftData, false);
+    printSettings->SetBoolean(printing::kSettingPreviewModifiable, false);
+    printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX);
+    printSettings->SetInteger(printing::kSettingCopies, 1);
+    printSettings->SetBoolean(printing::kSettingCollate, false);
+    printSettings->SetBoolean(printing::kSettingGenerateDraftData, false);
+    printSettings->SetBoolean(printing::kSettingPreviewModifiable, false);
+
+    printSettings->SetBoolean(printing::kSettingShouldPrintSelectionOnly, false);
+    printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds, false);
+    printSettings->SetBoolean(printing::kSettingHeaderFooterEnabled, false);
+    printSettings->SetString(printing::kSettingDeviceName, "");
+    printSettings->SetInteger(printing::kPreviewUIID, 12345678);
+
+    return printSettings;
+}
+
+static void applyQPageLayoutSettingsToDictionary(const QPageLayout &pageLayout, base::DictionaryValue &printSettings)
+{
     //Set page size attributes, chromium expects these in micrometers
     QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter);
     scoped_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue);
     sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter);
     sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter);
-    print_settings.Set(printing::kSettingMediaSize, std::move(sizeDict));
-
-    print_settings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
-
-    // The following are standard settings that Chromium expects to be set.
-    print_settings.SetBoolean(printing::kSettingPrintToPDF, true);
-    print_settings.SetBoolean(printing::kSettingCloudPrintDialog, false);
-    print_settings.SetBoolean(printing::kSettingPrintWithPrivet, false);
-    print_settings.SetBoolean(printing::kSettingPrintWithExtension, false);
-
-    print_settings.SetBoolean(printing::kSettingGenerateDraftData, false);
-    print_settings.SetBoolean(printing::kSettingPreviewModifiable, false);
-    print_settings.SetInteger(printing::kSettingColor, printing::COLOR);
-    print_settings.SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX);
-    print_settings.SetInteger(printing::kSettingDuplexMode, printing::UNKNOWN_DUPLEX_MODE);
-    print_settings.SetInteger(printing::kSettingCopies, 1);
-    print_settings.SetBoolean(printing::kSettingCollate, false);
-    print_settings.SetBoolean(printing::kSettingGenerateDraftData, false);
-    print_settings.SetBoolean(printing::kSettingPreviewModifiable, false);
-
-    print_settings.SetBoolean(printing::kSettingShouldPrintSelectionOnly, false);
-    print_settings.SetBoolean(printing::kSettingShouldPrintBackgrounds, false);
-    print_settings.SetBoolean(printing::kSettingHeaderFooterEnabled, false);
-    print_settings.SetString(printing::kSettingDeviceName, "");
-    print_settings.SetInteger(printing::kPreviewUIID, 12345678);
+    printSettings.Set(printing::kSettingMediaSize, std::move(sizeDict));
+
+    // Apply page margins
+    QMargins pageMarginsInPoints = pageLayout.marginsPoints();
+    scoped_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue);
+    marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top());
+    marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom());
+    marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left());
+    marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right());
+    printSettings.Set(printing::kSettingMarginsCustom, std::move(marginsDict));
+    printSettings.SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS);
+
+    printSettings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape);
 }
 
 } // namespace
@@ -149,20 +164,20 @@ PrintViewManagerQt::~PrintViewManagerQt()
 }
 
 #if defined(ENABLE_BASIC_PRINTING)
-bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, const QString &filePath)
+bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath)
 {
     if (m_printSettings || !filePath.length())
         return false;
 
     m_pdfOutputPath = toFilePath(filePath);
-    if (!PrintToPDFInternal(pageLayout)) {
+    if (!PrintToPDFInternal(pageLayout, printInColor)) {
         resetPdfState();
         return false;
     }
     return true;
 }
 
-bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, const PrintToPDFCallback& callback)
+bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback& callback)
 {
     if (callback.is_null())
         return false;
@@ -176,7 +191,7 @@ bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, c
     }
 
     m_pdfPrintCallback = callback;
-    if (!PrintToPDFInternal(pageLayout)) {
+    if (!PrintToPDFInternal(pageLayout, printInColor)) {
         content::BrowserThread::PostTask(content::BrowserThread::UI,
                                          FROM_HERE,
                                          base::Bind(callback, std::vector<char>()));
@@ -187,11 +202,13 @@ bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, c
     return true;
 }
 
-bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout)
+bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool printInColor)
 {
     if (!pageLayout.isValid())
         return false;
-    m_printSettings.reset(new base::DictionaryValue());
+    m_printSettings.reset(createPrintSettings());
+
+    m_printSettings->SetInteger(printing::kSettingColor, printInColor ? printing::COLOR : printing::GRAYSCALE);
     applyQPageLayoutSettingsToDictionary(pageLayout, *m_printSettings);
     return Send(new PrintMsg_InitiatePrintPreview(routing_id(), false));
 }
diff --git a/src/core/print_view_manager_qt.h b/src/core/print_view_manager_qt.h
index 8856a5b2b5c9bd86a4401c52a5ef75e60a018b20..668516096b5d3ab7a2b28c019ccdef783f249028 100644
--- a/src/core/print_view_manager_qt.h
+++ b/src/core/print_view_manager_qt.h
@@ -83,8 +83,8 @@ public:
     typedef base::Callback<void(const std::vector<char> &result)> PrintToPDFCallback;
 #if defined(ENABLE_BASIC_PRINTING)
     // Method to print a page to a Pdf document with page size \a pageSize in location \a filePath.
-    bool PrintToPDF(const QPageLayout& pageLayout, const QString& filePath);
-    bool PrintToPDFWithCallback(const QPageLayout& pageLayout, const PrintToPDFCallback& callback);
+    bool PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath);
+    bool PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback &callback);
 #endif  // ENABLE_BASIC_PRINTING
 
     // PrintedPagesSource implementation.
@@ -109,7 +109,7 @@ protected:
     void OnMetafileReadyForPrinting(const PrintHostMsg_DidPreviewDocument_Params& params);
 
 #if defined(ENABLE_BASIC_PRINTING)
-    bool PrintToPDFInternal(const QPageLayout &);
+    bool PrintToPDFInternal(const QPageLayout &, bool printInColor);
 #endif //
 
     base::FilePath m_pdfOutputPath;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index a7799544b9d50b1f46fbb6651440eefa423426b0..ea11d5e9ce4225f858af78be17c23b0493fcf542 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -50,6 +50,7 @@
 #include "browser_context_qt.h"
 #include "download_manager_delegate_qt.h"
 #include "media_capture_devices_dispatcher.h"
+#include "pdfium_printing_wrapper_qt.h"
 #include "print_view_manager_qt.h"
 #include "qwebenginecallback_p.h"
 #include "render_view_observer_host_qt.h"
@@ -91,6 +92,9 @@
 #include <QtGui/qaccessible.h>
 #include <QtGui/qdrag.h>
 #include <QtGui/qpixmap.h>
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+#include <QtPrintSupport/qprinter.h>
+#endif  // QT_NO_PRINTER
 #include <QtWebChannel/QWebChannel>
 
 namespace QtWebEngineCore {
@@ -189,6 +193,17 @@ static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient,
     }
 }
 
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+static void callbackOnPrintingOnPrinterFinished(WebContentsAdapterClient *adapterClient, int requestId, QPrinter *printer, const std::vector<char> &result)
+{
+    if (requestId) {
+        PdfiumPrintingWrapperQt printWrapper(result.data(), result.size());
+        bool printerResult = printWrapper.printOnPrinter(*printer);
+        adapterClient->didPrintPageOnPrinter(requestId, printerResult);
+    }
+}
+#endif // QT_NO_PRINTER
+
 static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext)
 {
     content::WebContents::CreateParams create_params(browserContext, NULL);
@@ -948,7 +963,7 @@ void WebContentsAdapter::wasHidden()
 void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString &filePath)
 {
 #if defined(ENABLE_BASIC_PRINTING)
-    PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, filePath);
+    PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, true, filePath);
 #endif // if defined(ENABLE_BASIC_PRINTING)
 }
 
@@ -956,13 +971,33 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo
 {
 #if defined(ENABLE_BASIC_PRINTING)
     Q_D(WebContentsAdapter);
-    PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, d->adapterClient, d->nextRequestId);
-    PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, callback);
+    PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished
+                                                                 , d->adapterClient
+                                                                 , d->nextRequestId);
+    PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, true
+                                                                               , callback);
+    return d->nextRequestId++;
+#else
+    return 0;
+#endif // if defined(ENABLE_BASIC_PRINTING)
+}
+
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+quint64 WebContentsAdapter::printOnPrinterCallbackResult(QPrinter *printer)
+{
+#if defined(ENABLE_BASIC_PRINTING)
+    Q_D(WebContentsAdapter);
+    PrintViewManagerQt::PrintToPDFCallback callback
+            = base::Bind(&callbackOnPrintingOnPrinterFinished, d->adapterClient
+                         , d->nextRequestId, printer);
+    PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(
+                printer->pageLayout(), printer->colorMode() == QPrinter::Color, callback);
     return d->nextRequestId++;
 #else
     return 0;
 #endif // if defined(ENABLE_BASIC_PRINTING)
 }
+#endif // QT_NO_PRINTER
 
 QPointF WebContentsAdapter::lastScrollOffset() const
 {
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 08f68e76baeff439c0c34a2e499ca21a3419b16c..7a109770ed5e5fbfb7bcd21140b791ba9f6117cf 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -58,6 +58,9 @@ class QAccessibleInterface;
 class QDragEnterEvent;
 class QDragMoveEvent;
 class QPageLayout;
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+class QPrinter;
+#endif // QT_NO_PRINTER
 class QString;
 class QWebChannel;
 QT_END_NAMESPACE
@@ -174,6 +177,10 @@ public:
     void printToPDF(const QPageLayout&, const QString&);
     quint64 printToPDFCallbackResult(const QPageLayout &);
 
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+    quint64 printOnPrinterCallbackResult(QPrinter *printer);
+#endif
+
     // meant to be used within WebEngineCore only
     content::WebContents *webContents() const;
     void replaceMisspelling(const QString &word);
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 31786a8f8b2ee9949924342cce1f316713819879..165d84e37cbc31037852c99dcc42b28b5e1ad19b 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -234,6 +234,9 @@ public:
     virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
     virtual void didFindText(quint64 requestId, int matchCount) = 0;
     virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0;
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+    virtual void didPrintPageOnPrinter(quint64 requestId, bool result) = 0;
+#endif
     virtual void passOnFocus(bool reverse) = 0;
     // returns the last QObject (QWidget/QQuickItem) based object in the accessibility
     // hierarchy before going into the BrowserAccessibility tree
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 7e5e07b95b543c872c73e2c6ec58b3a08c252a23..60692b8aef88284e45acb83375f7ee4cf8030a66 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -168,6 +168,9 @@ public:
     virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { }
     virtual void didFindText(quint64, int) Q_DECL_OVERRIDE;
     virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
+#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
+    virtual void didPrintPageOnPrinter(quint64, bool) Q_DECL_OVERRIDE { }
+#endif
     virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
     virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
     virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index c180699f365080f0f7f617a0d30275f3a29f41e2..428cccd9acd7500202dc8ba3fc1dd548a1676e09 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -373,6 +373,13 @@ void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &re
     m_callbacks.invoke(requestId, result);
 }
 
+#ifndef QT_NO_PRINTER
+void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result)
+{
+    m_callbacks.invoke(requestId, result);
+}
+#endif
+
 void QWebEnginePagePrivate::passOnFocus(bool reverse)
 {
     if (view)
@@ -1841,6 +1848,28 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
     d->m_callbacks.registerCallback(requestId, resultCallback);
 }
 
+#ifndef QT_NO_PRINTER
+/*!
+    \fn void QWebEnginePage::print(const QPrinter &printer, FunctorOrLambda resultCallback)
+    Renders the current content of the page into a temporary PDF document, then prints it using \a printer.
+
+    The settings for creating and printing the PDF document will be retrieved from the \a printer
+    object.
+    It is the users responsibility to ensure the \a printer remains valid until \a resultCallback
+    has been called.
+
+    The \a resultCallback must take a boolean as parameter. If printing was successful, this
+    boolean will have the value \c true, otherwise, its value will be \c false.
+    \since 5.8
+*/
+void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
+{
+    Q_D(QWebEnginePage);
+    quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer);
+    d->m_callbacks.registerCallback(requestId, resultCallback);
+}
+#endif // QT_NO_PRINTER
+
 /*!
     \since 5.7
 
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index bb46cd9fb07b5b626f11a58ea5c3d57579b9671b..923c3bb7026300238c3147cc9d17bb9f8b84caf0 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -54,6 +54,9 @@
 
 QT_BEGIN_NAMESPACE
 class QMenu;
+#ifndef QT_NO_PRINTER
+class QPrinter;
+#endif
 class QWebChannel;
 class QWebEngineContextMenuData;
 class QWebEngineFullScreenRequest;
@@ -280,6 +283,14 @@ public:
     void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF()));
 #endif
 
+#ifndef QT_NO_PRINTER
+#ifdef Q_QDOC
+    void print(QPrinter *printer, FunctorOrLambda resultCallback)
+#else
+    void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback);
+#endif // QDOC
+#endif // QT_NO_PRINTER
+
     const QWebEngineContextMenuData &contextMenuData() const;
     void viewSource();
     bool canViewSource() const;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 8d2a86350ee895a4ef67f47fd24b46762b2ef787..93ebdf6e6b4141820ae2d3a665ebbedc774b9a63 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -119,6 +119,9 @@ public:
     virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
     virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
     virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE;
+#ifndef QT_NO_PRINTER
+    virtual void didPrintPageOnPrinter(quint64 requestId, bool result) Q_DECL_OVERRIDE;
+#endif
     virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
     virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
     virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;