diff --git a/apps/app_page.c b/apps/app_page.c
index cea75cb5e43787b2066f67d01326c3b2c7cb6bc4..10a96b61beda2f0cbae6f1b5ab0acfc88520e09a 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -249,12 +249,18 @@ static void page_state_callback(struct ast_dial *dial)
 
 static int page_exec(struct ast_channel *chan, const char *data)
 {
-	char *tech, *resource, *tmp;
-	char confbridgeopts[128], originator[AST_CHANNEL_NAME];
+	char *tech;
+	char *resource;
+	char *tmp;
+	char *predial_callee = NULL;
+	char confbridgeopts[128];
+	char originator[AST_CHANNEL_NAME];
 	struct page_options options = { { 0, }, { 0, } };
 	unsigned int confid = ast_random();
 	struct ast_app *app;
-	int res = 0, pos = 0, i = 0;
+	int res = 0;
+	int pos = 0;
+	int i = 0;
 	struct ast_dial **dial_list;
 	unsigned int num_dials;
 	int timeout = 0;
@@ -310,6 +316,15 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		return -1;
 	}
 
+	/* PREDIAL: Preprocess any callee gosub arguments. */
+	if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
+		&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
+		ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLEE]);
+		predial_callee =
+			(char *) ast_app_expand_sub_args(chan, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+	}
+
+	/* PREDIAL: Run gosub on the caller's channel */
 	if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLER)
 		&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLER])) {
 		ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLER]);
@@ -360,9 +375,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		/* Set ANSWER_EXEC as global option */
 		ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
 
-		if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
-			&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
-			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+		if (predial_callee) {
+			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, predial_callee);
 		}
 
 		if (timeout) {
@@ -383,6 +397,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
 		dial_list[pos++] = dial;
 	}
 
+	ast_free(predial_callee);
+
 	if (!ast_test_flag(&options.flags, PAGE_QUIET)) {
 		res = ast_streamfile(chan, "beep", ast_channel_language(chan));
 		if (!res)
diff --git a/main/dial.c b/main/dial.c
index b935b6d8b693b2fff4fc51a399e3745556395507..34d2f70551a7fecd88f0ec22ace7a864a99b629f 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -378,14 +378,13 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
 	ast_channel_unlock(channel->owner);
 
 	if (!ast_strlen_zero(predial_string)) {
-		const char *predial_callee = ast_app_expand_sub_args(chan, predial_string);
-		if (!predial_callee) {
-			ast_log(LOG_ERROR, "Could not expand subroutine arguments in predial request '%s'\n", predial_string);
+		if (chan) {
+			ast_autoservice_start(chan);
+		}
+		ast_pre_call(channel->owner, predial_string);
+		if (chan) {
+			ast_autoservice_stop(chan);
 		}
-		ast_autoservice_start(chan);
-		ast_pre_call(channel->owner, predial_callee);
-		ast_autoservice_stop(chan);
-		ast_free((char *) predial_callee);
 	}
 
 	return 0;
@@ -397,10 +396,6 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_
 	int res = -1;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	AST_LIST_LOCK(&dial->channels);
 	AST_LIST_TRAVERSE(&dial->channels, channel, list) {
 		if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) {
@@ -450,10 +445,6 @@ static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async
 	int success = 0;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	/* Iterate through channel list, requesting and calling each one */
 	AST_LIST_LOCK(&dial->channels);
 	AST_LIST_TRAVERSE(&dial->channels, channel, list) {
@@ -473,10 +464,6 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c
 	char *tech = "Local", *device = tmp, *stuff;
 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL];
 
-	if (!ast_strlen_zero(predial_string)) {
-		ast_replace_subargument_delimiter(predial_string);
-	}
-
 	/* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */
 	if (FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING)) {
 		ast_hangup(original);