diff --git a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.html b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.html
index e0d1f5ba2..d4cd94aba 100644
--- a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.html
+++ b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.html
@@ -97,6 +97,8 @@
             self signed certificates.
         
followRedirects
         If set to false prevent following Redirect (HTTP 301).true by default
+        requestTimeout
+        If set to a positive number, will override the globally set httpRequestTimeout parameter.
     
     Outputs
     
diff --git a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
index 59f4f8fdc..594debc2e 100644
--- a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
+++ b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
@@ -92,6 +92,15 @@ module.exports = function(RED) {
             opts.maxRedirects = 21;
             opts.jar = request.jar();
             opts.proxy = null;
+            if (msg.requestTimeout) {
+                if (isNaN(msg.requestTimeout)) {
+                    node.warn(RED._("httpin.errors.timeout-isnan"));
+                } else if (msg.requestTimeout < 0) {
+                    node.warn(RED._("httpin.errors.timeout-isnegative"));
+                } else {
+                    opts.timeout = msg.requestTimeout;
+                }
+            }
             var ctSet = "Content-Type"; // set default camel case
             var clSet = "Content-Length";
             if (msg.headers) {
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
index f55179204..a6c6e1da2 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
@@ -410,7 +410,9 @@
             "json-error": "JSON parse error",
             "no-url": "No url specified",
             "deprecated-call":"Deprecated call to __method__",
-            "invalid-transport":"non-http transport requested"
+            "invalid-transport":"non-http transport requested",
+            "timeout-isnan": "Timeout value is not a valid number, ignoring",
+            "timeout-isnegative": "Timeout value is negative, ignoring"
         },
         "status": {
             "requesting": "requesting"
diff --git a/test/nodes/core/io/21-httprequest_spec.js b/test/nodes/core/io/21-httprequest_spec.js
index 8c39d8eac..a9ac49c99 100644
--- a/test/nodes/core/io/21-httprequest_spec.js
+++ b/test/nodes/core/io/21-httprequest_spec.js
@@ -35,11 +35,11 @@ var auth = require('basic-auth');
 describe('HTTP Request Node', function() {
     var testApp;
     var testServer;
-    var testPort = 9000;
+    var testPort = 10234;
     var testSslServer;
-    var testSslPort = 9100;
+    var testSslPort = 10334;
     var testProxyServer;
-    var testProxyPort = 9200;
+    var testProxyPort = 10444;
 
     //save environment variables
     var preEnvHttpProxyLowerCase;
@@ -132,6 +132,11 @@ describe('HTTP Request Node', function() {
                 res.send('hello');
             }, 10000);
         });
+        testApp.get('/timeout50ms', function(req, res){
+            setTimeout(function() {
+                res.send('hello');
+            }, 50);
+        });
         testApp.get('/checkCookie', function(req, res){
             var value = req.cookies.data;
             res.send(value);
@@ -844,7 +849,7 @@ describe('HTTP Request Node', function() {
             });
         });
 
-        it('shuold output an error when request timeout occurred', function(done) {
+        it('should output an error when request timeout occurred', function(done) {
             var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout')},
                 {id:"n2", type:"helper"}];
             var timeout = RED.settings.httpRequestTimeout;
@@ -871,8 +876,95 @@ describe('HTTP Request Node', function() {
                 n1.receive({payload:"foo"});
             });
         });
-    });
 
+        it('should output an error when request timeout occurred when set via msg.requestTimeout', function(done) {
+            var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout')},
+                {id:"n2", type:"helper"}];
+            helper.load(httpRequestNode, flow, function() {
+                var n1 = helper.getNode("n1");
+                var n2 = helper.getNode("n2");
+                n2.on("input", function(msg) {
+                    try {
+                        msg.should.have.property('statusCode','ESOCKETTIMEDOUT');
+                        var logEvents = helper.log().args.filter(function(evt) {
+                            return evt[0].type == 'http request';
+                        });
+                        logEvents.should.have.length(1);
+                        var tstmp = logEvents[0][0].timestamp;
+                        logEvents[0][0].should.eql({level:helper.log().ERROR, id:'n1',type:'http request',msg:'common.notification.errors.no-response', timestamp:tstmp});
+                        done();
+                    } catch(err) {
+                        done(err);
+                    }
+                });
+                n1.receive({payload:"foo", requestTimeout: 50});
+            });
+        });
+        it('should show a warning if msg.requestTimeout is not a number', function(done) {
+            var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')},
+                {id:"n2", type:"helper"}];
+            helper.load(httpRequestNode, flow, function() {
+                var n1 = helper.getNode("n1");
+                var n2 = helper.getNode("n2");
+                n2.on("input", function(msg) {
+                    try {
+                        msg.should.have.property('statusCode', 200);
+                        var logEvents = helper.log().args.filter(function(evt) {
+                            return evt[0].type == 'http request';
+                        });
+                        logEvents.should.have.length(2);
+                        var tstmp = logEvents[0][0].timestamp;
+                        logEvents[0][0].should.eql({level:helper.log().WARN, id:'n1',type:'http request',msg:'httpin.errors.timeout-isnan', timestamp:tstmp});
+                        done();
+                    } catch(err) {
+                        done(err);
+                    }
+                });
+                n1.receive({payload:"foo", requestTimeout: "foo"});
+            });
+        });
+        it('should show a warning if msg.requestTimeout is negative', function(done) {
+            var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/text')},
+                {id:"n2", type:"helper"}];
+            helper.load(httpRequestNode, flow, function() {
+                var n1 = helper.getNode("n1");
+                var n2 = helper.getNode("n2");
+                n2.on("input", function(msg) {
+                    try {
+                        msg.should.have.property('statusCode', 200);
+                        var logEvents = helper.log().args.filter(function(evt) {
+                            return evt[0].type == 'http request';
+                        });
+                        logEvents.should.have.length(2);
+                        var tstmp = logEvents[0][0].timestamp;
+                        logEvents[0][0].should.eql({level:helper.log().WARN, id:'n1',type:'http request',msg:'httpin.errors.timeout-isnegative', timestamp:tstmp});
+                        done();
+                    } catch(err) {
+                        done(err);
+                    }
+                });
+                n1.receive({payload:"foo", requestTimeout: -4});
+            });
+        });
+        it('should pass if response time is faster than timeout set via msg.requestTimeout', function(done) {
+            var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/timeout50ms')},
+                {id:"n2", type:"helper"}];
+            helper.load(httpRequestNode, flow, function() {
+                var n1 = helper.getNode("n1");
+                var n2 = helper.getNode("n2");
+                n2.on("input", function(msg) {
+                    try {
+                        msg.should.have.property('statusCode',200);
+                        done();
+                    } catch(err) {
+                        done(err);
+                    }
+                });
+                n1.receive({payload:"foo", requestTimeout: 100});
+            });
+        });
+
+    });
     describe('HTTP header', function() {
         it('should receive cookie', function(done) {
             var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/setCookie')},
@@ -913,7 +1005,7 @@ describe('HTTP Request Node', function() {
             });
         });
 
-        it('should send cookie with obejct data', function(done) {
+        it('should send cookie with object data', function(done) {
             var flow = [{id:"n1",type:"http request",wires:[["n2"]],method:"GET",ret:"obj",url:getTestURL('/checkCookie')},
                 {id:"n2", type:"helper"}];
             helper.load(httpRequestNode, flow, function() {