diff --git a/runtime/BrowserWindow.cpp b/runtime/BrowserWindow.cpp
index 5419c0e..d33b515 100644
--- a/runtime/BrowserWindow.cpp
+++ b/runtime/BrowserWindow.cpp
@@ -23,7 +23,6 @@
 #include <QInputDialog>
 #include <QLineEdit>
 #endif
-
 // App headers
 #include "BrowserWindow.h"
 #include "ConfigWindow.h"
@@ -42,6 +41,12 @@ BrowserWindow::BrowserWindow(QString url)
     m_widget = NULL;
     m_toolBtnBack = NULL;
     m_toolBtnForward = NULL;
+    downloadStarted = 0;
+    is_download_canceled = 0;
+    m_file = NULL;
+    downloadedFileName = "";
+    defaultFileName = "";
+    progressDlg = NULL;
 
     m_appServerUrl = url;
 
@@ -83,6 +88,11 @@ BrowserWindow::BrowserWindow(QString url)
     // Register the slot on tab index change
     connect(m_tabWidget,SIGNAL(currentChanged(int )),this,SLOT(tabIndexChanged(int )));
 
+    // Listen for the download file request from the web page
+    m_mainWebView->page()->setForwardUnsupportedContent(true);
+    connect(m_mainWebView->page(), SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(download(const QNetworkRequest &)));
+    connect(m_mainWebView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
+
     m_mainWebView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
 
     // Restore the geometry
@@ -199,6 +209,191 @@ int BrowserWindow::findURLTab(const QUrl &name)
     return 0;
 }
 
+// This slot will be called when user right click the download link and select "Save Link..."
+void BrowserWindow::download(const QNetworkRequest &request)
+{
+    if (downloadStarted)
+    {
+        //Inform the user that one download already started
+        QMessageBox::information(this, tr("Download warning"), tr("File download already in progress - %1").arg(defaultFileName));
+        return;
+    }
+
+    defaultFileName = QFileInfo(request.url().toString()).fileName();
+    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);
+    if (fileName.isEmpty())
+        return;
+    else
+    {
+        downloadedFileName = fileName;
+
+        QNetworkRequest newRequest = request;
+        newRequest.setAttribute(QNetworkRequest::User, fileName);
+
+        QObject *obj_web_page = QObject::sender();
+        if (obj_web_page != NULL)
+        {
+            QWebPage *sender_web_page = dynamic_cast<QWebPage*>(obj_web_page);
+            if (sender_web_page != NULL)
+            {
+                QNetworkAccessManager *networkManager = sender_web_page->networkAccessManager();
+                QNetworkReply *reply = networkManager->get(newRequest);
+                if (reply != NULL)
+                {
+                    downloadStarted = 1;
+                    is_download_canceled = 0;
+                    // Connect the signal for downloadprogress and downloadFinished for file download
+                    connect( reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadFileProgress(qint64, qint64)) );
+                    connect( reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+                }
+            }
+        }
+    }
+}
+
+//This slot will called in chunk and give the progress for the file download
+void BrowserWindow::downloadFileProgress(qint64 readData, qint64 totalData)
+{
+    QNetworkReply *reply = ((QNetworkReply*)sender());
+    QNetworkRequest request = reply->request();
+    QVariant v = request.attribute(QNetworkRequest::User);
+
+    // Is download is canceled by the user then no action is taken, just return
+    if (is_download_canceled)
+        return;
+
+    if(reply != NULL && reply->error() != QNetworkReply::NoError)
+    {
+        qDebug() << "Network error occured during downloding " << defaultFileName << " file";
+        return;
+    }
+
+    // Download is not yet started so open the file first time.
+    if (!m_file)
+    {
+        m_file = new QFile(downloadedFileName);
+        if (!m_file->open(QIODevice::WriteOnly))
+        {
+            qDebug() << "Error opening file: " << downloadedFileName;
+            downloadedFileName.clear();
+            defaultFileName.clear();
+            downloadStarted = 0;
+            return;
+        }
+
+        // Start downaloding progress bar
+        progressDlg = new QProgressDialog (tr("Downloading file...%1 ").arg(defaultFileName), "Cancel", readData, totalData, this);
+        progressDlg->setWindowTitle("Download progress..");
+        progressDlg->setMinimumWidth(450);
+        progressDlg->setMinimumHeight(80);
+        progressDlg->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
+        QObject::connect(progressDlg, SIGNAL(canceled()), this, SLOT(progressCanceled()));
+        progressDlg->show();
+    }
+
+    if (m_file)
+    {
+        // Write the data to file
+        m_file->write(reply->read(readData));
+        progressDlg->setValue(readData);
+        // As read data and totalData difference is zero means downloading is finished
+        if ((totalData - readData) == 0)
+        {
+            if (progressDlg)
+            {
+                delete progressDlg;
+                progressDlg = NULL;
+            }
+
+            // Downloading complted so we need to display the message
+            // Inform user that downloading is completed
+            QMessageBox::information(this, tr("Download completed"), tr("%1 file downloaded successfully").arg(defaultFileName));
+            downloadedFileName.clear();
+            defaultFileName.clear();
+            downloadStarted = 0;
+            is_download_canceled = 0;
+            if (m_file)
+            {
+                delete m_file;
+                m_file = NULL;
+            }
+        }
+    }
+}
+
+//This slot will called when user cancel the downloading file which is in progress.
+void BrowserWindow::progressCanceled()
+{
+    is_download_canceled = 1;
+
+    if (progressDlg)
+    {
+        delete progressDlg;
+        progressDlg = NULL;
+    }
+
+    if (m_file)
+    {
+        delete m_file;
+        m_file = NULL;
+    }
+
+    downloadedFileName.clear();
+    defaultFileName.clear();
+    downloadStarted = 0;
+}
+
+// This slot will called when file downloading is finished
+void BrowserWindow::downloadFinished()
+{
+    if (progressDlg)
+    {
+        delete progressDlg;
+        progressDlg = NULL;
+    }
+
+    // Inform user that downloading is completed
+    if (downloadStarted)
+        QMessageBox::information(this, tr("Download completed"), tr("%1 file downloaded successfully").arg(defaultFileName));
+
+    downloadedFileName.clear();
+    defaultFileName.clear();
+    downloadStarted = 0;
+    is_download_canceled = 0;
+    if (m_file)
+    {
+        delete m_file;
+        m_file = NULL;
+    }
+}
+
+// This slot will be called when user directly click on any download file
+void BrowserWindow::unsupportedContent(QNetworkReply * reply)
+{
+    if (downloadStarted)
+    {
+        //Inform the user that one download already started
+        QMessageBox::information(this, tr("Download warning"), tr("File download already in progress - %1").arg(defaultFileName));
+        return;
+    }
+
+    defaultFileName = QFileInfo(reply->url().toString()).fileName();
+    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);
+    if (fileName.isEmpty())
+        return;
+    else
+    {
+        downloadedFileName = fileName;
+        if (reply != NULL)
+        {
+            downloadStarted = 1;
+            is_download_canceled = 0;
+            connect( reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadFileProgress(qint64, qint64)));
+            connect( reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
+        }
+    }
+}
+
 // Slot: When the tab index change, hide/show the toolbutton displayed on tab
 void BrowserWindow::tabIndexChanged(int index)
 {
@@ -343,6 +538,40 @@ void BrowserWindow::tabTitleChanged(const QString &str)
 // Slot: Link is open from pgAdmin mainwindow
 void BrowserWindow::urlLinkClicked(const QUrl &name)
 {
+    QString csv_data = QString::fromUtf8(name.toEncoded());
+
+    // Find the "data:text/csv" tag, get the decoded data from QUrl class and write to csv file.
+    if (csv_data.contains(QRegExp("^data:text\/csv")))
+    {
+        // Ask user where to save the csv file in filesystem.
+        QString filename = QFileDialog::getSaveFileName(this, tr("Save csv file"), QDir::currentPath(), tr("Files (*.csv)") );
+        if(!filename.isEmpty())
+        {
+            // Decode the encoded uri data
+            QString csvData = QUrl::fromPercentEncoding(name.toEncoded());
+            QStringList csvStrList = csvData.split(";");
+            QString extractString = "";
+            if (csvStrList.size() >= 3)
+                extractString = csvStrList.at(2);
+            QFile csvfile(filename);
+            if (!csvfile.open(QIODevice::WriteOnly | QIODevice::Text))
+            {
+                QMessageBox::information(this, tr("Save csv file"), tr("Error while opening file %1").arg(filename));
+                return;
+            }
+            // Write the csv data to file
+	    qint64 data_return = csvfile.write(extractString.toUtf8().constData());
+            if (data_return == -1)
+            {
+                QMessageBox::information(this, tr("Save csv file"), tr("Error while writing data to file %1").arg(filename));
+                csvfile.close();
+                return;
+            }
+            csvfile.close();
+        }
+        return;
+    }
+
     // First check is there any tab opened with same URL then open it again.
     int tabFound = findURLTab(name);
 
@@ -353,6 +582,11 @@ void BrowserWindow::urlLinkClicked(const QUrl &name)
         m_addNewGridLayout->setContentsMargins(0, 0, 0, 0);
         m_addNewWebView = new WebViewWindow(m_addNewTab);
 
+	// Listen for the download request from the web page
+	m_addNewWebView->page()->setForwardUnsupportedContent(true);
+        connect(m_addNewWebView->page(), SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(download(const QNetworkRequest &)));
+        connect(m_addNewWebView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*)));
+
         m_widget = new QWidget(m_addNewTab);
         m_toolBtnBack = new QToolButton(m_widget);
         m_toolBtnBack->setFixedHeight(PGA_BTN_SIZE);
diff --git a/runtime/BrowserWindow.h b/runtime/BrowserWindow.h
index 43f90fe..d0e4150 100644
--- a/runtime/BrowserWindow.h
+++ b/runtime/BrowserWindow.h
@@ -54,6 +54,11 @@ public slots:
     void tabIndexChanged(int index);
     void goBackPage();
     void goForwardPage();
+    void download(const QNetworkRequest &request);
+    void unsupportedContent(QNetworkReply * reply);
+    void downloadFinished();
+    void downloadFileProgress(qint64 , qint64 );
+    void progressCanceled();
 
 private:
     QString m_appServerUrl;
@@ -79,6 +84,12 @@ private:
 
     bool m_initialLoad;
     int m_loadAttempt;
+    QString downloadedFileName;
+    int downloadStarted;
+    int is_download_canceled;
+    QFile *m_file;
+    QProgressDialog *progressDlg;
+    QString defaultFileName;
 
     void createActions();
     void pause(int seconds = 1);
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
index c2282a1..535b543 100644
--- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
@@ -2571,7 +2571,7 @@ define(
                 keys = _.pluck(self.columns, 'name');
 
             // Fetch the items from fullCollection and convert it as csv format
-            var csv = labels.join(',') + '\n';
+            var csv = keys.join(',') + '\n';
             csv += coll.map(function(item) {
                 return _.map(keys, function(key) {
                   var cell = csv_col [key].cell,
@@ -2584,7 +2584,7 @@ define(
             }).join('\n');
 
             // Download the file.
-            var encodedUri = encodeURI('data:text/csv;charset=utf-8,' + csv),
+            var encodedUri = encodeURI('data:text/csv;charset=utf-8;' + csv),
                     link = document.createElement('a');
             link.setAttribute('href', encodedUri);
 
